You've already forked lazarus-ccr
fpspreadsheet: Remove fix for Excel's Year-1900 problem because it creates new issues... (issue #38742).
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@8033 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -821,29 +821,17 @@ begin
|
|||||||
if (AExcelDateNum < 1) and (AExcelDateNum >= 0) then
|
if (AExcelDateNum < 1) and (AExcelDateNum >= 0) then
|
||||||
begin
|
begin
|
||||||
Result := AExcelDateNum;
|
Result := AExcelDateNum;
|
||||||
end
|
end else
|
||||||
else
|
|
||||||
begin
|
begin
|
||||||
case ADateMode of
|
case ADateMode of
|
||||||
dm1900:
|
dm1900:
|
||||||
begin
|
begin
|
||||||
Result := AExcelDateNum + DATEMODE_1900_BASE - 1.0;
|
Result := AExcelDateNum + DATEMODE_1900_BASE - 1.0;
|
||||||
// Excel and Lotus 1-2-3 incorrectly assume that 1900 was a leap year
|
{ Excel and Lotus 1-2-3 incorrectly assume that 1900 was a leap year
|
||||||
// Therefore all dates before March 01 are off by 1.
|
Therefore all dates before March 01 are off by 1.
|
||||||
// The old fps implementation corrected only Feb 29, but all days are
|
Unlike earlier fps versions we no longer attempt to fix this issue
|
||||||
// wrong!
|
because it leads to other issues (when dates are in order then
|
||||||
if AExcelDateNum < 61 then
|
the weekdays are off by 1!) }
|
||||||
Result := Result + 1.0;
|
|
||||||
(*
|
|
||||||
|
|
||||||
// Check for Lotus 1-2-3 bug with 1900 leap year
|
|
||||||
if AExcelDateNum=61.0 then
|
|
||||||
// 29 feb does not exist, change to 28
|
|
||||||
// Spell out that we remove a day for ehm "clarity".
|
|
||||||
result := 61.0 - 1.0 + DATEMODE_1900_BASE - 1.0
|
|
||||||
else
|
|
||||||
result := AExcelDateNum + DATEMODE_1900_BASE - 1.0;
|
|
||||||
*)
|
|
||||||
end;
|
end;
|
||||||
dm1904:
|
dm1904:
|
||||||
result := AExcelDateNum + DATEMODE_1904_BASE;
|
result := AExcelDateNum + DATEMODE_1904_BASE;
|
||||||
@ -857,17 +845,21 @@ function ConvertDateTimeToExcelDateTime(const ADateTime: TDateTime;
|
|||||||
ADateMode: TDateMode): Double;
|
ADateMode: TDateMode): Double;
|
||||||
begin
|
begin
|
||||||
// Time only
|
// Time only
|
||||||
if (ADateTime<1) and (ADateTime>=0) then
|
if (ADateTime < 1) and (ADateTime >= 0) then
|
||||||
begin
|
begin
|
||||||
Result:=ADateTime;
|
Result := ADateTime;
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
case ADateMode of
|
case ADateMode of
|
||||||
dm1900:
|
dm1900:
|
||||||
begin
|
begin
|
||||||
|
{ Excel and Lotus 1-2-3 incorrectly assume that 1900 was a leap year
|
||||||
|
Therefore all dates before March 01 are off by 1.
|
||||||
|
Unlike earlier fps versions we no longer attempt to fix this issue
|
||||||
|
because it leads to other issues (when dates are in order then
|
||||||
|
the weekdays are off by 1!) }
|
||||||
Result := ADateTime - DATEMODE_1900_BASE + 1.0;
|
Result := ADateTime - DATEMODE_1900_BASE + 1.0;
|
||||||
if Result < 61 then Result := Result - 1.0;
|
|
||||||
end;
|
end;
|
||||||
dm1904:
|
dm1904:
|
||||||
Result := ADateTime - DATEMODE_1904_BASE;
|
Result := ADateTime - DATEMODE_1904_BASE;
|
||||||
@ -1507,7 +1499,9 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
{@@ ----------------------------------------------------------------------------
|
{@@ ----------------------------------------------------------------------------
|
||||||
Converts the number to a date/time and return that if it is
|
Converts the number to a date/time and returns that if it is
|
||||||
|
Like LibreOffice Calc, we do not attempt to fix the Year-1900 issue of Excel
|
||||||
|
files because it leads to even more confusion...
|
||||||
-------------------------------------------------------------------------------}
|
-------------------------------------------------------------------------------}
|
||||||
function TsSpreadBIFFReader.IsDateTime(Number: Double;
|
function TsSpreadBIFFReader.IsDateTime(Number: Double;
|
||||||
ANumberFormat: TsNumberFormat; ANumberFormatStr: String;
|
ANumberFormat: TsNumberFormat; ANumberFormatStr: String;
|
||||||
@ -2250,7 +2244,7 @@ begin
|
|||||||
end else
|
end else
|
||||||
cell := sheet.AddCell(ARow, ACol); // "real" cell
|
cell := sheet.AddCell(ARow, ACol); // "real" cell
|
||||||
|
|
||||||
if IsDateTime(value, nf, nfs, dt) then // Year-1900 correction occurs here!
|
if IsDateTime(value, nf, nfs, dt) then // DateMode correction occurs here!
|
||||||
sheet.WriteDateTime(cell, dt, nf, nfs)
|
sheet.WriteDateTime(cell, dt, nf, nfs)
|
||||||
else if nf = nfText then
|
else if nf = nfText then
|
||||||
sheet.WriteText(cell, GeneralFormatFloat(value, FWorkbook.FormatSettings))
|
sheet.WriteText(cell, GeneralFormatFloat(value, FWorkbook.FormatSettings))
|
||||||
@ -4189,11 +4183,11 @@ var
|
|||||||
cf: TsCellFormat;
|
cf: TsCellFormat;
|
||||||
nfp: TsNumFormatParams;
|
nfp: TsNumFormatParams;
|
||||||
begin
|
begin
|
||||||
// We must correct the bug of Lotus 1-2-3 which had ignored that year 1900 was
|
// We must convert the date value to the Excel date basis (DateMode),
|
||||||
// a leap year, but only for "normal" date format, not for time-interval formats
|
// but not for time-interval formats.
|
||||||
cf := TsWorksheet(FWorksheet).ReadCellFormat(ACell);
|
cf := TsWorksheet(FWorksheet).ReadCellFormat(ACell);
|
||||||
nfp := TsWorkbook(FWorkbook).GetNumberFormat(cf.NumberFormatIndex);
|
nfp := TsWorkbook(FWorkbook).GetNumberFormat(cf.NumberFormatIndex);
|
||||||
if IsTimeIntervalFormat(nfp) then //or IsTimeFormat(nfp) then
|
if IsTimeIntervalFormat(nfp) then
|
||||||
ExcelDateSerial := AValue
|
ExcelDateSerial := AValue
|
||||||
else
|
else
|
||||||
ExcelDateSerial := ConvertDateTimeToExcelDateTime(AValue, FDateMode);
|
ExcelDateSerial := ConvertDateTimeToExcelDateTime(AValue, FDateMode);
|
||||||
|
@ -2745,6 +2745,7 @@ var
|
|||||||
fmt: PsCellFormat;
|
fmt: PsCellFormat;
|
||||||
begin
|
begin
|
||||||
Unused(ARow, ACol);
|
Unused(ARow, ACol);
|
||||||
|
(*
|
||||||
fmt := (FWorkbook as TsWorkbook).GetPointerToCellFormat(ACell^.FormatIndex);
|
fmt := (FWorkbook as TsWorkbook).GetPointerToCellFormat(ACell^.FormatIndex);
|
||||||
if (fmt <> nil) and (uffNumberFormat in fmt^.UsedFormattingFields) then
|
if (fmt <> nil) and (uffNumberFormat in fmt^.UsedFormattingFields) then
|
||||||
begin
|
begin
|
||||||
@ -2764,9 +2765,10 @@ begin
|
|||||||
end;
|
end;
|
||||||
if valueStr = '' then
|
if valueStr = '' then
|
||||||
begin
|
begin
|
||||||
|
*)
|
||||||
ExcelDate := ConvertDateTimeToExcelDateTime(AValue, FDateMode);
|
ExcelDate := ConvertDateTimeToExcelDateTime(AValue, FDateMode);
|
||||||
valueStr := FormatDateTime('yyyy-mm-dd"T"hh:nn:ss.zzz', ExcelDate);
|
valueStr := FormatDateTime('yyyy-mm-dd"T"hh:nn:ss.zzz', ExcelDate);
|
||||||
end;
|
//end;
|
||||||
|
|
||||||
AppendToStream(AStream, Format(CELL_INDENT +
|
AppendToStream(AStream, Format(CELL_INDENT +
|
||||||
'<Cell%s%s%s%s%s>' + LF + VALUE_INDENT + // colIndex, style, formula, hyperlink, merge
|
'<Cell%s%s%s%s%s>' + LF + VALUE_INDENT + // colIndex, style, formula, hyperlink, merge
|
||||||
|
@ -1043,7 +1043,8 @@ begin
|
|||||||
begin
|
begin
|
||||||
if IsDateTimeFormat(numFmt) then
|
if IsDateTimeFormat(numFmt) then
|
||||||
begin
|
begin
|
||||||
if not IsTimeIntervalFormat(numFmt) then // no correction of time origin for "time interval" format
|
if not IsTimeIntervalFormat(numFmt) then
|
||||||
|
// no correction of time origin for "time" or "time interval" format
|
||||||
number := ConvertExcelDateTimeToDateTime(number, FDateMode);
|
number := ConvertExcelDateTimeToDateTime(number, FDateMode);
|
||||||
sheet.WriteDateTime(cell, number);
|
sheet.WriteDateTime(cell, number);
|
||||||
end
|
end
|
||||||
|
Reference in New Issue
Block a user