Skip to content

Commit 9847b6f

Browse files
Mirrors the fix for issue 869 on the master branch (#873)
* Mirrors the fix for issue 869 on the master branch * Fixing test and early return property set --------- Co-authored-by: RiRiSharp <[email protected]>
1 parent 5647439 commit 9847b6f

File tree

5 files changed

+71
-0
lines changed

5 files changed

+71
-0
lines changed
8.28 KB
Binary file not shown.
8.34 KB
Binary file not shown.

src/MiniExcel/IConfiguration.cs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,28 @@ public abstract class Configuration : IConfiguration
1515
/// When exporting using DataReader, the data not in DynamicColumn will be filtered.
1616
/// </summary>
1717
public bool DynamicColumnFirst { get; set; } = false;
18+
19+
/// <summary>
20+
/// Specifies when and how DateTime values are converted to DateOnly values.
21+
/// </summary>
22+
public DateOnlyConversionMode DateOnlyConversionMode { get; set; }
23+
}
24+
25+
public enum DateOnlyConversionMode
26+
{
27+
/// <summary>
28+
/// No conversion is applied and DateOnly values are not transformed.
29+
/// </summary>
30+
None,
31+
32+
/// <summary>
33+
/// Allows conversion from DateTime to DateOnly only if the time component is exactly midnight (00:00:00).
34+
/// </summary>
35+
RequireMidnight,
36+
37+
/// <summary>
38+
/// Converts DateTime to DateOnly by ignoring the time part completely, assuming the time component is not critical.
39+
/// </summary>
40+
IgnoreTimePart
1841
}
1942
}

src/MiniExcel/Utils/TypeHelper.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,16 @@ public static bool IsNumericType(Type type, bool isNullableUnderlyingType = fals
142142
pInfo.Property.SetValue(v, newValue);
143143
return newValue;
144144
}
145+
146+
if (itemValue is DateTime dateTimeValue && config.DateOnlyConversionMode != DateOnlyConversionMode.None)
147+
{
148+
if (config.DateOnlyConversionMode == DateOnlyConversionMode.RequireMidnight && dateTimeValue.TimeOfDay != TimeSpan.Zero)
149+
throw new InvalidCastException($"Could not convert cell of type DateTime to DateOnly, because DateTime was not at midnight, but at {dateTimeValue:HH:mm:ss}.");
150+
151+
newValue = DateOnly.FromDateTime(dateTimeValue);
152+
pInfo.Property.SetValue(v, newValue);
153+
return newValue;
154+
}
145155

146156
var vs = itemValue?.ToString();
147157
if (pInfo.ExcelFormat != null)

tests/MiniExcelTests/MiniExcelIssueTests.cs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4661,4 +4661,42 @@ public void TestIssue809()
46614661
Assert.Equal(null, rows[0].A);
46624662
Assert.Equal(2, rows[2].B);
46634663
}
4664+
4665+
4666+
private class Issue869
4667+
{
4668+
public string? Name { get; set; }
4669+
public DateOnly? Date { get; set; }
4670+
}
4671+
4672+
[Theory]
4673+
[InlineData("DateTimeMidnight", DateOnlyConversionMode.None, true)]
4674+
[InlineData("DateTimeNotMidnight", DateOnlyConversionMode.None, true)]
4675+
[InlineData("DateTimeMidnight", DateOnlyConversionMode.RequireMidnight, false)]
4676+
[InlineData("DateTimeNotMidnight", DateOnlyConversionMode.RequireMidnight, true)]
4677+
[InlineData("DateTimeMidnight", DateOnlyConversionMode.IgnoreTimePart, false)]
4678+
[InlineData("DateTimeNotMidnight", DateOnlyConversionMode.IgnoreTimePart, false)]
4679+
public void TestIssue869(string fileName, DateOnlyConversionMode mode, bool throwsException)
4680+
{
4681+
var path = PathHelper.GetFile($"xlsx/TestIssue869/{fileName}.xlsx");
4682+
var config = new OpenXmlConfiguration { DateOnlyConversionMode = mode };
4683+
4684+
var testFn = () => MiniExcel.Query<Issue869>(path, configuration: config).ToList();
4685+
if (throwsException)
4686+
{
4687+
Assert.Throws<ExcelInvalidCastException>(testFn);
4688+
}
4689+
else
4690+
{
4691+
try
4692+
{
4693+
var result = testFn();
4694+
Assert.Equal(new DateOnly(2025, 1, 1), result[0].Date);
4695+
}
4696+
catch (Exception ex)
4697+
{
4698+
Assert.Fail($"No exception should be thrown, but one was still thrown: {ex}.");
4699+
}
4700+
}
4701+
}
46644702
}

0 commit comments

Comments
 (0)