Skip to content

Commit b6b668a

Browse files
Moving DateOnlyConversionMode to the Enums folder and renaming the EnforceMidnight option to RequireMidnight
1 parent 9c417d9 commit b6b668a

File tree

4 files changed

+67
-70
lines changed

4 files changed

+67
-70
lines changed
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
namespace MiniExcelLib.Core.Enums;
2+
3+
4+
public enum DateOnlyConversionMode
5+
{
6+
/// <summary>
7+
/// No conversion is applied and DateOnly values are not transformed.
8+
/// </summary>
9+
None,
10+
11+
/// <summary>
12+
/// Allows conversion from DateTime to DateOnly only if the time component is exactly midnight (00:00:00).
13+
/// </summary>
14+
RequireMidnight,
15+
16+
/// <summary>
17+
/// Converts DateTime to DateOnly by ignoring the time part completely, assuming the time component is not critical.
18+
/// </summary>
19+
IgnoreTimePart
20+
}
Lines changed: 4 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using MiniExcelLib.Core.Attributes;
2+
using MiniExcelLib.Core.Enums;
23

34
namespace MiniExcelLib.Core;
45

@@ -17,29 +18,7 @@ public abstract class MiniExcelBaseConfiguration : IMiniExcelConfiguration
1718
public bool DynamicColumnFirst { get; set; } = false;
1819

1920
/// <summary>
20-
/// Sets the options to how and when encountered DateTime values can be converted to DateOnly values.
21+
/// Specifies when and how DateTime values are converted to DateOnly values.
2122
/// </summary>
22-
public DateOnlyConversionMode DateOnlyConversionMode { get; set; } = DateOnlyConversionMode.None;
23-
}
24-
25-
26-
/// <summary>
27-
/// Specifies how DateTime values should be converted to DateOnly.
28-
/// </summary>
29-
public enum DateOnlyConversionMode
30-
{
31-
/// <summary>
32-
/// No conversion is applied; DateOnly values are not transformed.
33-
/// </summary>
34-
None,
35-
36-
/// <summary>
37-
/// Converts DateTime to DateOnly by enforcing midnight (00:00:00) as the time component.
38-
/// </summary>
39-
EnforceMidnight,
40-
41-
/// <summary>
42-
/// Converts DateTime to DateOnly by ignoring the time part completely, assuming the time component is not critical.
43-
/// </summary>
44-
IgnoreTimePart
45-
}
23+
public DateOnlyConversionMode DateOnlyConversionMode { get; set; }
24+
}

src/MiniExcel.Core/Reflection/MiniExcelMapper.cs

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System.ComponentModel;
2+
using MiniExcelLib.Core.Enums;
23
using MiniExcelLib.Core.Exceptions;
34

45
namespace MiniExcelLib.Core.Reflection;
@@ -150,15 +151,11 @@ public static partial class MiniExcelMapper
150151
return newValue;
151152
}
152153

153-
if (itemValue is DateTime dateTimeValue &&
154-
config.DateOnlyConversionMode is DateOnlyConversionMode.EnforceMidnight
155-
or DateOnlyConversionMode.IgnoreTimePart)
154+
if (itemValue is DateTime dateTimeValue && config.DateOnlyConversionMode is not DateOnlyConversionMode.None)
156155
{
157-
if (config.DateOnlyConversionMode == DateOnlyConversionMode.EnforceMidnight && dateTimeValue.TimeOfDay != TimeSpan.Zero)
158-
{
159-
throw new InvalidCastException(
160-
$"Could not convert cell of type DateTime to DateOnly, because DateTime was not at midnight, but at {dateTimeValue:HH:mm:ss}.");
161-
}
156+
if (config.DateOnlyConversionMode == DateOnlyConversionMode.RequireMidnight && dateTimeValue.TimeOfDay != TimeSpan.Zero)
157+
throw new InvalidCastException($"Could not convert cell of type DateTime to DateOnly, because DateTime was not at midnight, but at {dateTimeValue:HH:mm:ss}.");
158+
162159
return DateOnly.FromDateTime(dateTimeValue);
163160
}
164161

tests/MiniExcel.Core.Tests/MiniExcelIssueTests.cs

Lines changed: 38 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System.ComponentModel;
22
using System.Text.RegularExpressions;
3+
using MiniExcelLib.Core.Enums;
34
using MiniExcelLib.Core.Exceptions;
45
using MiniExcelLib.Core.OpenXml.Picture;
56
using MiniExcelLib.Core.OpenXml.Utils;
@@ -16,44 +17,7 @@ public class MiniExcelIssueTests(ITestOutputHelper output)
1617
private readonly OpenXmlExporter _excelExporter = MiniExcel.Exporters.GetOpenXmlExporter();
1718
private readonly OpenXmlTemplater _excelTemplater = MiniExcel.Templaters.GetOpenXmlTemplater();
1819

19-
// private readonly OpenXmlImporter _csvImporter = MiniExcel.Importer.GetCsvImporter();
20-
// private readonly OpenXmlExporter _csvExporter = MiniExcel.Exporter.GetCsvExporter();
21-
22-
[Theory]
23-
[InlineData("DateTimeMidnight", DateOnlyConversionMode.None, true)]
24-
[InlineData("DateTimeNotMidnight", DateOnlyConversionMode.None, true)]
25-
[InlineData("DateTimeMidnight", DateOnlyConversionMode.EnforceMidnight, false)]
26-
[InlineData("DateTimeNotMidnight", DateOnlyConversionMode.EnforceMidnight, true)]
27-
[InlineData("DateTimeMidnight", DateOnlyConversionMode.IgnoreTimePart, false)]
28-
[InlineData("DateTimeNotMidnight", DateOnlyConversionMode.IgnoreTimePart, false)]
29-
public void TestIssue869(string fileName, DateOnlyConversionMode mode, bool throwsException)
30-
{
31-
var path = PathHelper.GetFile($"xlsx/TestIssue869/{fileName}.xlsx");
32-
var config = new OpenXmlConfiguration { DateOnlyConversionMode = mode };
33-
var testFn = () => _excelImporter.Query<DateTimeSheet>(path, configuration: config).ToList();
34-
if (throwsException)
35-
{
36-
Assert.Throws<MiniExcelInvalidCastException>(testFn);
37-
}
38-
else
39-
{
40-
try
41-
{
42-
_ = testFn();
43-
}
44-
catch (Exception ex)
45-
{
46-
Assert.Fail($"No exception should be thrown, but still one was thrown: {ex.Message}.");
47-
}
48-
}
49-
}
5020

51-
private class DateTimeSheet
52-
{
53-
public string? Name { get; set; }
54-
public DateOnly? Date { get; set; }
55-
}
56-
5721
/// <summary>
5822
/// https://github.com/mini-software/MiniExcel/issues/549
5923
/// </summary>
@@ -3688,4 +3652,41 @@ public void TestIssue809()
36883652
Assert.Equal(null, rows[0].A);
36893653
Assert.Equal(2, rows[2].B);
36903654
}
3655+
3656+
3657+
private class Issue869
3658+
{
3659+
public string? Name { get; set; }
3660+
public DateOnly? Date { get; set; }
3661+
}
3662+
3663+
[Theory]
3664+
[InlineData("DateTimeMidnight", DateOnlyConversionMode.None, true)]
3665+
[InlineData("DateTimeNotMidnight", DateOnlyConversionMode.None, true)]
3666+
[InlineData("DateTimeMidnight", DateOnlyConversionMode.RequireMidnight, false)]
3667+
[InlineData("DateTimeNotMidnight", DateOnlyConversionMode.RequireMidnight, true)]
3668+
[InlineData("DateTimeMidnight", DateOnlyConversionMode.IgnoreTimePart, false)]
3669+
[InlineData("DateTimeNotMidnight", DateOnlyConversionMode.IgnoreTimePart, false)]
3670+
public void TestIssue869(string fileName, DateOnlyConversionMode mode, bool throwsException)
3671+
{
3672+
var path = PathHelper.GetFile($"xlsx/TestIssue869/{fileName}.xlsx");
3673+
var config = new OpenXmlConfiguration { DateOnlyConversionMode = mode };
3674+
3675+
var testFn = () => _excelImporter.Query<Issue869>(path, configuration: config).ToList();
3676+
if (throwsException)
3677+
{
3678+
Assert.Throws<MiniExcelInvalidCastException>(testFn);
3679+
}
3680+
else
3681+
{
3682+
try
3683+
{
3684+
_ = testFn();
3685+
}
3686+
catch (Exception ex)
3687+
{
3688+
Assert.Fail($"No exception should be thrown, but one was still thrown: {ex}.");
3689+
}
3690+
}
3691+
}
36913692
}

0 commit comments

Comments
 (0)