Skip to content

Commit aed1276

Browse files
saulius-saltenis-DevoteamSaulius Saltenis
andauthored
fix: UTC dateTimes convertor (#266)
* - convert dateTime to UTC equivalent * - support DateTimeKind.Local * test: add datetime conversion tests * test: rewrite datetime conversion tests to check with local timezone offsets --------- Co-authored-by: Saulius Saltenis <[email protected]>
1 parent bb5a493 commit aed1276

File tree

2 files changed

+67
-1
lines changed

2 files changed

+67
-1
lines changed

src/Gridify/Builder/BaseQueryBuilder.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,12 @@ private object AddIndexerNullCheck(LambdaExpression mapTarget, object query)
204204
{
205205
if (mapper.Configuration.DefaultDateTimeKind.HasValue)
206206
{
207-
value = DateTime.SpecifyKind(dateTime, mapper.Configuration.DefaultDateTimeKind.Value);
207+
value = mapper.Configuration.DefaultDateTimeKind.Value switch
208+
{
209+
DateTimeKind.Local => dateTime.ToLocalTime(),
210+
DateTimeKind.Utc => dateTime.ToUniversalTime(),
211+
_ => dateTime
212+
};
208213
}
209214
}
210215
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
using EntityFrameworkIntegrationTests.cs;
2+
using Gridify;
3+
using Microsoft.EntityFrameworkCore;
4+
using Xunit;
5+
6+
namespace EntityFrameworkPostgreSqlIntegrationTests;
7+
8+
public class PR266Tests
9+
{
10+
private readonly MyDbContext _dbContext = new();
11+
12+
[Fact]
13+
public void ISO_Should_Convert_ToUTC()
14+
{
15+
var isoTimestamp = "2025-03-31T02:54:09Z";
16+
17+
var mapper = new GridifyMapper<User>(q => q.DefaultDateTimeKind = DateTimeKind.Utc).GenerateMappings();
18+
var queryString = _dbContext.Users.ApplyFiltering($"CreateDate={isoTimestamp}", mapper).ToQueryString();
19+
20+
var whereClause = queryString.Split("WHERE")[1].Trim();
21+
Assert.Equal($"u.\"CreateDate\" = TIMESTAMPTZ '{isoTimestamp}'", whereClause);
22+
}
23+
24+
[Fact]
25+
public void ISO_Should_ShowcaseDifferentConversions_LocalToUtc()
26+
{
27+
var localOffset = TimeZoneInfo.Local.GetUtcOffset(DateTime.Now);
28+
29+
var localDt = DateTime.Parse("2025-03-31T02:54:09Z");
30+
Assert.Equal(DateTimeKind.Local, localDt.Kind);
31+
32+
// Past behavior. Kind becomes Utc, but time is not converted.
33+
var utcDtWrong = DateTime.SpecifyKind(localDt, DateTimeKind.Utc);
34+
Assert.Equal(DateTimeKind.Utc, utcDtWrong.Kind);
35+
Assert.Equal(localDt, utcDtWrong);
36+
37+
// Current behavior. Kind becomes Utc, and time is converted.
38+
var utcDtCorrect = localDt.ToUniversalTime();
39+
Assert.Equal(DateTimeKind.Utc, utcDtCorrect.Kind);
40+
Assert.Equal(localDt.Subtract(localOffset), utcDtCorrect);
41+
}
42+
43+
[Fact]
44+
public void ISO_Should_ShowcaseDifferentConversions_UtcToLocal()
45+
{
46+
var localOffset = TimeZoneInfo.Local.GetUtcOffset(DateTime.Now);
47+
48+
var utcDt = DateTime.Parse("2025-03-31T02:54:09Z").ToUniversalTime();
49+
Assert.Equal(DateTimeKind.Utc, utcDt.Kind);
50+
51+
// Past behavior. Kind becomes Local, but time is not converted.
52+
var localDtWrong = DateTime.SpecifyKind(utcDt, DateTimeKind.Local);
53+
Assert.Equal(DateTimeKind.Local, localDtWrong.Kind);
54+
Assert.Equal(utcDt, localDtWrong);
55+
56+
// Current behavior. Kind becomes Local, and time is converted.
57+
var localDtCorrect = utcDt.ToLocalTime();
58+
Assert.Equal(DateTimeKind.Local, localDtCorrect.Kind);
59+
Assert.Equal(utcDt.Add(localOffset), localDtCorrect);
60+
}
61+
}

0 commit comments

Comments
 (0)