fpspreadsheet: In the unit tests, use the same methods for creating "soll" date/times and test format strings. --> No more biff-related regressions.

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@3078 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2014-05-22 12:34:10 +00:00
parent c70b1db64f
commit ee1db37c7f
4 changed files with 86 additions and 49 deletions

View File

@ -45,6 +45,8 @@ begin
}
// Write some number cells
MyWorksheet.WriteDateTime(0, 0, EncodeDate(2012,1,12)+EncodeTime(13,14,15,0), nfShortTimeAM);
(*
MyWorksheet.WriteNumber(0, 0, 1.0);
MyWorksheet.WriteUsedFormatting(0, 0, [uffBold, uffNumberFormat]);
MyWorksheet.WriteNumber(0, 1, 2.0);
@ -378,7 +380,7 @@ begin
MyWorksheet.WriteRowInfo(5, lRow);
lRow.Height := 5;
MyWorksheet.WriteRowInfo(6, lRow);
*)
// Save the spreadsheet to a file
MyWorkbook.WriteToFile(MyDir + 'test' + STR_EXCEL_EXTENSION, sfExcel2, true);
MyWorkbook.Free;

View File

@ -86,9 +86,14 @@ function BuildNumberFormatString(ANumberFormat: TsNumberFormat;
ACurrencySymbol: String = '?'): String;
function BuildDateTimeFormatString(ANumberFormat: TsNumberFormat;
const AFormatSettings: TFormatSettings; AFormatString: String = ''): String;
function AddAMPM(const ATimeFormatString: String;
const AFormatSettings: TFormatSettings): String;
function StripAMPM(const ATimeFormatString: String): String;
function CountDecs(AFormatString: String; ADecChars: TsDecsChars = ['0']): Byte;
function AddIntervalBrackets(AFormatString: String): String;
function SpecialDateTimeFormat(ACode: String;
const AFormatSettings: TFormatSettings; ForWriting: Boolean): String;
function SciFloat(AValue: Double; ADecimals: Byte): String;
//function TimeIntervalToString(AValue: TDateTime; AFormatStr: String): String;
@ -784,20 +789,12 @@ function BuildDateTimeFormatString(ANumberFormat: TsNumberFormat;
const AFormatSettings: TFormatSettings; AFormatString: String = '') : string;
var
fmt: String;
am, pm: String;
begin
case ANumberFormat of
nfFmtDateTime:
begin
fmt := lowercase(AFormatString);
if (fmt = 'dm') then Result := 'd/mmm'
else if (fmt = 'my') then Result := 'mmm/yy'
else if (fmt = 'ms') then Result := 'nn:ss'
else if (fmt = 'msz') then Result := 'nn:ss.z'
else Result := AFormatString;
end;
Result := SpecialDateTimeFormat(lowercase(AFormatString), AFormatSettings, false);
nfShortDateTime:
Result := AFormatSettings.ShortDateFormat + ' ' + FormatSettings.ShortTimeFormat;
Result := AFormatSettings.ShortDateFormat + ' ' + AFormatSettings.ShortTimeFormat;
// In the DefaultFormatSettings this is: d/m/y hh:nn
nfShortDate:
Result := AFormatSettings.ShortDateFormat; // --> d/m/y
@ -810,20 +807,14 @@ begin
nfShortTimeAM:
begin // --> hh:nn AM/PM
Result := AFormatSettings.ShortTimeFormat;
if (pos('a', lowercase(AFormatSettings.ShortTimeFormat)) = 0) then begin
am := IfThen(AFormatSettings.TimeAMString = '', 'AM', AFormatSettings.TimeAMString);
pm := IfThen(AFormatSettings.TimePMString = '', 'PM', AFormatSettings.TimePMString);
Result := Format('%s %s/%s', [Result, am, pm]);
end;
if (pos('a', lowercase(AFormatSettings.ShortTimeFormat)) = 0) then
Result := AddAMPM(Result, AFormatSettings);
end;
nfLongTimeAM: // --> hh:nn:ss AM/PM
begin
Result := AFormatSettings.LongTimeFormat;
if pos('a', lowercase(AFormatSettings.LongTimeFormat)) = 0 then begin
am := IfThen(AFormatSettings.TimeAMString = '', 'AM', AFormatSettings.TimeAMString);
pm := IfThen(AFormatSettings.TimePMString = '', 'PM', AFormatSettings.TimePMString);
Result := Format('%s %s/%s', [Result, am, pm]);
end;
if pos('a', lowercase(AFormatSettings.LongTimeFormat)) = 0 then
Result := AddAMPM(Result, AFormatSettings);
end;
nfTimeInterval: // --> [h]:nn:ss
if AFormatString = '' then
@ -904,19 +895,22 @@ begin
end;
if ANumberFormat in [nfCurrency, nfCurrencyRed] then
Result := Result +';' + Format(POS_FMT[cf], ['0' + decs, ACurrencySymbol])
{
Result := Result + ';0' + decs;
if cf in [2,3] then
Result := Format('%s "%s"', [Result, ACurrencySymbol])
else
Result := Format('%s"%s"', [Result, ACurrencySymbol]);
}
else
Result := Result + ';-';
end;
end;
end;
function AddAMPM(const ATimeFormatString: String;
const AFormatSettings: TFormatSettings): String;
var
am, pm: String;
begin
am := IfThen(AFormatSettings.TimeAMString <> '', AFormatSettings.TimeAMString, 'AM');
pm := IfThen(AFormatSettings.TimePMString <> '', AFormatSettings.TimePMString, 'PM');
Result := Format('%s %s/%s', [StripAMPM(ATimeFormatString), am, pm]);
end;
function StripAMPM(const ATimeFormatString: String): String;
var
i: Integer;
@ -968,6 +962,42 @@ begin
end;
end;
{ Creates the formatstrings for the date/time codes "dm", "my", "ms" and "msz"
out of the formatsettings. }
function SpecialDateTimeFormat(ACode: String;
const AFormatSettings: TFormatSettings; ForWriting: Boolean): String;
var
pd, pm, py: Integer;
sdf: String;
MonthChar, MinuteChar, MillisecChar: Char;
begin
if ForWriting then begin
MonthChar := 'M'; MinuteChar := 'm'; MillisecChar := '0';
end else begin
MonthChar := 'm'; MinuteChar := 'n'; MillisecChar := 'z';
end;
ACode := lowercase(ACode);
sdf := lowercase(AFormatSettings.ShortDateFormat);
pd := pos('d', sdf);
pm := pos('m', sdf);
py := pos('y', sdf);
if ACode = 'dm' then begin
Result := DupeString(MonthChar, 3);
Result := IfThen(pd < py, 'd/'+Result, Result+'/d'); // d/mmm
end else
if ACode = 'my' then begin
Result := DupeString(MonthChar, 3);
Result := IfThen(pm < py, Result+'/yy', 'yy/'+Result); // mmm/yy
end else
if ACode = 'ms' then begin
Result := DupeString(MinuteChar, 2) + ':ss'; // mm:ss
end
else if ACode = 'msz' then
Result := DupeString(MinuteChar, 2) + ':ss.' + MillisecChar // mm:ss.z
else
Result := ACode;
end;
{ Formats the number AValue in "scientific" format with the given number of
decimals. "Scientific" is the same as "exponential", but with exponents rounded
to multiples of 3 (like for "kilo" - "Mega" - "Giga" etc.). }

View File

@ -127,9 +127,12 @@ const
procedure InitSollFmtData;
var
i: Integer;
fs: TFormatSettings;
begin
// Set up norm - MUST match spreadsheet cells exactly
fs := DefaultFormatSettings;
// Numbers
SollNumbers[0] := 0.0;
SollNumbers[1] := 1.0;
@ -182,13 +185,13 @@ begin
for i:=Low(SollDateTimes) to High(SollDateTimes) do begin
SollDateTimeStrings[i, 0] := DateToStr(SollDateTimes[i]) + ' ' + FormatDateTime('t', SollDateTimes[i]);
SollDateTimeStrings[i, 1] := DateToStr(SollDateTimes[i]);
SollDateTimeStrings[i, 2] := FormatDateTime('hh:nn', SollDateTimes[i]);
SolLDateTimeStrings[i, 3] := FormatDateTime('hh:nn:ss', SollDateTimes[i]);
SollDateTimeStrings[i, 4] := FormatDateTime('hh:nn am/pm', SollDateTimes[i]); // dont't use "t" - it does the hours wrong
SollDateTimeStrings[i, 5] := FormatDateTime('hh:nn:ss am/pm', SollDateTimes[i]);
SollDateTimeStrings[i, 6] := FormatDateTime('dd/mmm', SollDateTimes[i]);
SollDateTimeStrings[i, 7] := FormatDateTime('mmm/yy', SollDateTimes[i]);
SollDateTimeStrings[i, 8] := FormatDateTime('nn:ss', SollDateTimes[i]);
SollDateTimeStrings[i, 2] := FormatDateTime(fs.ShortTimeFormat, SollDateTimes[i]);
SolLDateTimeStrings[i, 3] := FormatDateTime(fs.LongTimeFormat, SollDateTimes[i]);
SollDateTimeStrings[i, 4] := FormatDateTime(fs.ShortTimeFormat + ' am/pm', SollDateTimes[i]); // dont't use "t" - it does the hours wrong
SollDateTimeStrings[i, 5] := FormatDateTime(fs.LongTimeFormat + ' am/pm', SollDateTimes[i]);
SollDateTimeStrings[i, 6] := FormatDateTime(SpecialDateTimeFormat('dm', fs, false), SollDateTimes[i]);
SollDateTimeStrings[i, 7] := FormatDateTime(SpecialDateTimeFormat('my', fs, false), SollDateTimes[i]);
SollDateTimeStrings[i, 8] := FormatDateTime(SpecialDateTimeFormat('ms', fs, false), SollDateTimes[i]);
SollDateTimeStrings[i, 9] := FormatDateTime('[h]:mm:ss', SollDateTimes[i], [fdoInterval]);
end;

View File

@ -176,11 +176,13 @@ end;
procedure TsBIFF2NumFormatList.AddBuiltinFormats;
var
fs: TFormatSettings;
ds, ts, cs: string;
begin
ds := DefaultFormatSettings.DecimalSeparator;
ts := DefaultFormatSettings.ThousandSeparator;
cs := DefaultFormatSettings.CurrencyString;
fs := Workbook.FormatSettings;
ds := fs.DecimalSeparator;
ts := fs.ThousandSeparator;
cs := fs.CurrencyString;
AddFormat( 0, '', nfGeneral);
AddFormat( 1, '0', nfFixed, 0);
AddFormat( 2, '0'+ds+'00', nfFixed, 2); // 0.00
@ -193,15 +195,15 @@ begin
AddFormat( 9, '0%', nfPercentage, 0);
AddFormat(10, '0'+ds+'00%', nfPercentage, 2);
AddFormat(11, '0'+ds+'00E+00', nfExp, 2);
AddFormat(12, 'M/D/YY', nfShortDate);
AddFormat(13, 'D-MMM-YY', nfLongDate);
AddFormat(14, 'D-MMM', nfFmtDateTime);
AddFormat(15, 'MMM-YY', nfFmtDateTime);
AddFormat(16, 'h:mm AM/PM', nfShortTimeAM);
AddFormat(17, 'h:mm:ss AM/PM', nfLongTimeAM);
AddFormat(18, 'h:mm', nfShortTime);
AddFormat(19, 'h:mm:ss', nfLongTime);
AddFormat(20, 'M/D/YY h:mm', nfShortDateTime);
AddFormat(12, fs.ShortDateFormat, nfShortDate);
AddFormat(13, fs.LongDateFormat, nfLongDate);
AddFormat(14, SpecialDateTimeFormat('dm', fs, true), nfFmtDateTime);
AddFormat(15, SpecialDateTimeFormat('my', fs, true), nfFmtDateTime);
AddFormat(16, AddAMPM(fs.ShortTimeFormat, fs), nfShortTimeAM);
AddFormat(17, AddAMPM(fs.LongTimeFormat, fs), nfLongTimeAM);
AddFormat(18, fs.ShortTimeFormat, nfShortTime);
AddFormat(19, fs.LongTimeFormat, nfLongTime);
AddFormat(20, fs.ShortDateFormat + ' ' + fs.ShortTimeFormat, nfShortDateTime);
FFirstFormatIndexInFile := 0; // BIFF2 stores built-in formats to file.
FNextFormatIndex := 21; // not needed - there are not user-defined formats
@ -231,7 +233,7 @@ begin
(fmt = 'dd-mm') or (fmt = 'dd/mm') or
(fmt = 'dd-mmm') or (fmt = 'dd/mmm')
then
AFormatString := 'D-MMM'
AFormatString := SpecialDateTimeFormat('dm', Workbook.FormatSettings, true)
else
if (fmt = 'm-yy') or (fmt = 'm/yy') or
(fmt = 'mm-yy') or (fmt = 'mm/yy') or
@ -240,7 +242,7 @@ begin
(fmt = 'mm-yyyy') or (fmt = 'mm/yyyy') or
(fmt = 'mmm-yyyy') or (fmt = 'mmm-yyyy')
then
AFormatString := 'MMM-YY'
AFormatString := SpecialDateTimeFormat('my', Workbook.FormatSettings, true)
else
if (copy(fmt, 1, 5) = 'nn:ss') or (copy(fmt, 1, 5) = 'mm:ss') or
(copy(fmt, 1, 4) = 'n:ss') or (copy(fmt, 1, 4) = 'm:ss')