You've already forked lazarus-ccr
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:
@ -19,6 +19,7 @@ const
|
|||||||
psErrNoUsableFormat = 5;
|
psErrNoUsableFormat = 5;
|
||||||
psErrNoValidNumberFormat = 6;
|
psErrNoValidNumberFormat = 6;
|
||||||
psErrNoValidDateTimeFormat = 7;
|
psErrNoValidDateTimeFormat = 7;
|
||||||
|
psAmbiguousSymbol = 8;
|
||||||
|
|
||||||
{ TsNumFormatParser }
|
{ TsNumFormatParser }
|
||||||
|
|
||||||
@ -524,10 +525,13 @@ var
|
|||||||
nf: TsNumberFormat;
|
nf: TsNumberFormat;
|
||||||
partStr: String;
|
partStr: String;
|
||||||
isAMPM: Boolean;
|
isAMPM: Boolean;
|
||||||
|
isDate: Boolean; // to distinguish whether "m" means "month" or "minute" (along with FIsTime)
|
||||||
|
P: PChar;
|
||||||
begin
|
begin
|
||||||
done := false;
|
done := false;
|
||||||
s := '';
|
s := '';
|
||||||
isAMPM := false;
|
isAMPM := false;
|
||||||
|
isDate := false;
|
||||||
|
|
||||||
while (FCurrent <= FEnd) and (FStatus = psOK) and (not done) do begin
|
while (FCurrent <= FEnd) and (FStatus = psOK) and (not done) do begin
|
||||||
token := FCurrent^;
|
token := FCurrent^;
|
||||||
@ -535,54 +539,87 @@ begin
|
|||||||
'\': // means that the next character is taken literally
|
'\': // means that the next character is taken literally
|
||||||
begin
|
begin
|
||||||
inc(FCurrent); // skip the "\"...
|
inc(FCurrent); // skip the "\"...
|
||||||
token := FCurrent^; // and take the next character
|
if FCurrent <= FEnd then begin
|
||||||
s := s + token;
|
token := FCurrent^; // and take the next character
|
||||||
|
s := s + token;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
'Y', 'y':
|
'Y', 'y':
|
||||||
begin
|
begin
|
||||||
ScanDateTimeParts(token, token, s);
|
ScanDateTimeParts(token, token, s);
|
||||||
FIsTime := false;
|
FIsTime := false;
|
||||||
|
isDate := true;
|
||||||
end;
|
end;
|
||||||
'M':
|
'm', 'M':
|
||||||
if FConversionDirection = cdToFPSpreadsheet then
|
if (token = 'M') and (FConversionDirection = cdToFPSpreadsheet) then
|
||||||
|
// Uppercase "M" in Excel = "month" --> "m" in fpspreadsheet
|
||||||
ScanDateTimeParts(token, 'm', s)
|
ScanDateTimeParts(token, 'm', s)
|
||||||
else begin
|
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;
|
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':
|
'N', 'n':
|
||||||
if FConversionDirection = cdToFPSpreadsheet then begin
|
if FConversionDirection = cdToFPSpreadsheet then begin
|
||||||
// "n" is not used by file format --> stop scanning date/time
|
// "n" is not used by file format --> stop scanning date/time
|
||||||
done := true;
|
done := true;
|
||||||
dec(FCurrent);
|
dec(FCurrent);
|
||||||
end else
|
end else
|
||||||
// "n", in fpc, stands for "minute".
|
// "n", in fpc, stands for "minute". Excel wants "m"
|
||||||
ScanDateTimeParts(token, 'm', s);
|
ScanDateTimeParts(token, 'm', s);
|
||||||
'D', 'd':
|
'D', 'd':
|
||||||
begin
|
begin
|
||||||
ScanDateTimeParts(token, token, s);
|
ScanDateTimeParts(token, token, s);
|
||||||
FIsTime := false;
|
FIsTime := false;
|
||||||
|
isDate := true;
|
||||||
end;
|
end;
|
||||||
'H', 'h':
|
'H', 'h':
|
||||||
begin
|
begin
|
||||||
ScanDateTimeParts(token, token, s);
|
ScanDateTimeParts(token, token, s);
|
||||||
FIsTime := true;
|
FIsTime := true;
|
||||||
|
isDate := false;
|
||||||
end;
|
end;
|
||||||
'S', 's':
|
'S', 's':
|
||||||
begin
|
begin
|
||||||
ScanDateTimeParts(token, token, s);
|
ScanDateTimeParts(token, token, s);
|
||||||
FIsTime := true;
|
FIsTime := true;
|
||||||
|
isDate := false;
|
||||||
end;
|
end;
|
||||||
'/', ':', '.', ']', '[', ' ':
|
'/', ':', '.', ']', '[', ' ':
|
||||||
s := s + token;
|
s := s + token;
|
||||||
|
@ -1937,7 +1937,7 @@ begin
|
|||||||
// 2 var. Number format string (Unicode string, 16-bit string length, ➜2.5.3)
|
// 2 var. Number format string (Unicode string, 16-bit string length, ➜2.5.3)
|
||||||
fmtString := ReadWideString(AStream, False);
|
fmtString := ReadWideString(AStream, False);
|
||||||
|
|
||||||
// Add to the list
|
// Analyze the format string and add format to the list
|
||||||
NumFormatList.AnalyzeAndAdd(fmtIndex, fmtString);
|
NumFormatList.AnalyzeAndAdd(fmtIndex, fmtString);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user