fpspreadsheet: Improved detection of the ambivalent symbol "m" in format strings.

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@3077 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2014-05-22 10:09:35 +00:00
parent 169dbe7b4f
commit c70b1db64f
2 changed files with 56 additions and 19 deletions

View File

@ -19,6 +19,7 @@ const
psErrNoUsableFormat = 5;
psErrNoValidNumberFormat = 6;
psErrNoValidDateTimeFormat = 7;
psAmbiguousSymbol = 8;
{ TsNumFormatParser }
@ -524,10 +525,13 @@ var
nf: TsNumberFormat;
partStr: String;
isAMPM: Boolean;
isDate: Boolean; // to distinguish whether "m" means "month" or "minute" (along with FIsTime)
P: PChar;
begin
done := false;
s := '';
isAMPM := false;
isDate := false;
while (FCurrent <= FEnd) and (FStatus = psOK) and (not done) do begin
token := FCurrent^;
@ -535,54 +539,87 @@ begin
'\': // means that the next character is taken literally
begin
inc(FCurrent); // skip the "\"...
token := FCurrent^; // and take the next character
s := s + token;
if FCurrent <= FEnd then begin
token := FCurrent^; // and take the next character
s := s + token;
end;
end;
'Y', 'y':
begin
ScanDateTimeParts(token, token, s);
FIsTime := false;
isDate := true;
end;
'M':
if FConversionDirection = cdToFPSpreadsheet then
'm', 'M':
if (token = 'M') and (FConversionDirection = cdToFPSpreadsheet) then
// Uppercase "M" in Excel = "month" --> "m" in fpspreadsheet
ScanDateTimeParts(token, 'm', s)
else begin
if FIsTime then ScanDateTimeParts(token, 'm', s) else ScanDateTimeParts(token, 'M', s);
// not clear if "m" means "month" or "minute" -> look for next symbols
if (not isDate) and (not FIsTime) then begin
P := FCurrent;
inc(P);
while (P <= FEnd) and not done do begin
token := P^;
case token of
'd','D','y','Y':
begin
isDate := true; // ok - it means "month"
FIsTime := false;
break;
end;
'h','H','s','S':
begin
isDate := false;
FIsTime := true; // ok - it means "minute"
break;
end;
else
inc(P);
end;
end;
if P > FEnd then begin
// Special case of isolated "m" --> Error
FStatus := psAmbiguousSymbol;
break;
end;
end;
if FIsTime then // is "minute"
case FConversionDirection of
cdToFPSpreadsheet : ScanDateTimeParts(token, 'n', s);
cdFromFPSpreadsheet: ScanDateTimeParts(token, 'm', s);
end
else if isDate then // is "month"
case FConversionDirection of
cdToFPSpreadsheet : ScanDateTimeParts(token, 'm', s);
cdFromFPSpreadsheet: ScanDateTimeParts(token, 'M', s);
end;
end;
'm':
if FConversionDirection = cdToFPSpreadsheet then
ScanDateTimeParts(token, 'n', s)
else
ScanDateTimeParts(token, 'm', s);
{
if FConversionDirection = cdToFPSpreadsheet then begin
if FIsTime then ScanDateTimeParts(token, 'n', s) else ScanDateTimeParts(token, 'm', s)
end else begin
if FIsTime then ScanDateTimeParts(token, 'm', s) else ScanDateTimeParts(token, 'M', s);
end;
}
'N', 'n':
if FConversionDirection = cdToFPSpreadsheet then begin
// "n" is not used by file format --> stop scanning date/time
done := true;
dec(FCurrent);
end else
// "n", in fpc, stands for "minute".
// "n", in fpc, stands for "minute". Excel wants "m"
ScanDateTimeParts(token, 'm', s);
'D', 'd':
begin
ScanDateTimeParts(token, token, s);
FIsTime := false;
isDate := true;
end;
'H', 'h':
begin
ScanDateTimeParts(token, token, s);
FIsTime := true;
isDate := false;
end;
'S', 's':
begin
ScanDateTimeParts(token, token, s);
FIsTime := true;
isDate := false;
end;
'/', ':', '.', ']', '[', ' ':
s := s + token;

View File

@ -1937,7 +1937,7 @@ begin
// 2 var. Number format string (Unicode string, 16-bit string length, ➜2.5.3)
fmtString := ReadWideString(AStream, False);
// Add to the list
// Analyze the format string and add format to the list
NumFormatList.AnalyzeAndAdd(fmtIndex, fmtString);
end;