diff --git a/source/Sylvan.Data.Excel/ExcelDataReader.cs b/source/Sylvan.Data.Excel/ExcelDataReader.cs index 4b045c5..1a1a301 100644 --- a/source/Sylvan.Data.Excel/ExcelDataReader.cs +++ b/source/Sylvan.Data.Excel/ExcelDataReader.cs @@ -47,7 +47,7 @@ public abstract partial class ExcelDataReader : DbDataReader, IDisposable, IDbCo private protected int rowCount; private protected int rowFieldCount; - static readonly DateTime Epoch1900 = new DateTime(1899, 12, 31); + static readonly DateTime Epoch1900 = new DateTime(1899, 12, 30); static readonly DateTime Epoch1904 = new DateTime(1904, 1, 1); private protected DateMode dateMode; @@ -704,6 +704,7 @@ static internal bool TryGetDate(ExcelFormat fmt, double value, DateMode mode, ou { dt = DateTime.MinValue; DateTime epoch = Epoch1904; + // Excel doesn't render negative values as dates. if (value < 0.0) return false; if (mode == DateMode.Mode1900) @@ -727,12 +728,11 @@ static internal bool TryGetDate(ExcelFormat fmt, double value, DateMode mode, ou if (value >= 60d) { // 1900 wasn't a leapyear, but Excel thinks it was + // values in this range are in-expressible as .NET dates + // Excel renders it as 1900-2-29 (not a real day) return false; } - } - else - { - value -= 1; + value += 1; } } dt = epoch.AddDays(value); diff --git a/source/Sylvan.Data.Excel/Xlsx/XlsxDataWriter+FieldWriter.cs b/source/Sylvan.Data.Excel/Xlsx/XlsxDataWriter+FieldWriter.cs index eb4f567..f4ec007 100644 --- a/source/Sylvan.Data.Excel/Xlsx/XlsxDataWriter+FieldWriter.cs +++ b/source/Sylvan.Data.Excel/Xlsx/XlsxDataWriter+FieldWriter.cs @@ -7,7 +7,7 @@ namespace Sylvan.Data.Excel.Xlsx; partial class XlsxDataWriter { - static DateTime Epoch = new DateTime(1900, 1, 1, 0, 0, 0, DateTimeKind.Unspecified); + static DateTime Epoch = new DateTime(1899, 12, 30, 0, 0, 0, DateTimeKind.Unspecified); sealed class Context { @@ -228,7 +228,7 @@ public static void WriteDateTime(Context c, DateTime value) var w = c.xw; w.Write(""); - var val = (value - Epoch).TotalDays + 2; + var val = (value - Epoch).TotalDays; #if SPAN var scratch = c.GetCharBuffer(); if (val.TryFormat(scratch.AsSpan(), out var sl, default, CultureInfo.InvariantCulture)) @@ -288,7 +288,7 @@ public static void WriteDateOnly(Context c, DateOnly value) var w = c.xw; w.Write(""); - var val = (value.ToDateTime(Midnight) - Epoch).TotalDays + 2; + var val = (value.ToDateTime(Midnight) - Epoch).TotalDays; var scratch = c.GetCharBuffer(); if (val.TryFormat(scratch.AsSpan(), out var sl, default, CultureInfo.InvariantCulture))