Fix DateTimeOffset Now and UtcNow (#235)

* Fix DateTimeOffset Now and UtcNow
pull/237/head
Christopher Jolly 2 years ago committed by GitHub
parent d8d47443f0
commit 6ad608581b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -217,6 +217,10 @@ namespace EntityFrameworkCore.Jet.Data
{
return DateTimeOffset.Parse(stringValue, null, DateTimeStyles.RoundtripKind);
}
else if (value is DateTime dateTimeValue && dateTimeValue == JetConfiguration.TimeSpanOffset)
{
return default;
}
else if (value is DateTime dateTime)
{
return new DateTimeOffset(dateTime, TimeSpan.Zero);

@ -2,6 +2,7 @@
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Reflection;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Diagnostics;
@ -77,8 +78,18 @@ namespace EntityFrameworkCore.Jet.Query.ExpressionTranslators.Internal
{
nameof(DateTime.Now) => _sqlExpressionFactory.Function("NOW", Array.Empty<SqlExpression>(),
false, new[] { false }, returnType),
nameof(DateTime.UtcNow) => _sqlExpressionFactory.Function("NOW", Array.Empty<SqlExpression>(),
false, new[] { false }, returnType),
nameof(DateTime.UtcNow) => _sqlExpressionFactory.Function(
"DATEADD",
new SqlExpression[]
{
new SqlConstantExpression(Expression.Constant("n"), null),
new SqlConstantExpression(Expression.Constant(-1 * TimeZoneInfo.Local.BaseUtcOffset.TotalMinutes), null) ,
_sqlExpressionFactory.Function("NOW", Array.Empty<SqlExpression>(),
false, new[] { false }, returnType)
},
true,
argumentsPropagateNullability: new[] { false, false, true },
returnType),
nameof(DateTime.Today) => _sqlExpressionFactory.Function(
"DATEVALUE",
new[]

@ -37,7 +37,7 @@ namespace EntityFrameworkCore.Jet.Storage.Internal
// OLE DB can't handle the DateTimeOffset type.
if (parameter.Value is DateTimeOffset dateTimeOffset)
{
parameter.Value = dateTimeOffset.UtcDateTime;
parameter.Value = dateTimeOffset.Ticks == 0 ? DateTime.FromOADate(0) : dateTimeOffset.UtcDateTime;
parameter.DbType = System.Data.DbType.DateTime;
}
@ -50,7 +50,7 @@ namespace EntityFrameworkCore.Jet.Storage.Internal
protected override string GenerateNonNullSqlLiteral(object value)
{
if (value is not DateTimeOffset offset) return base.GenerateNonNullSqlLiteral(value);
var dateTime = offset.UtcDateTime;
var dateTime = offset.Ticks == 0 ? DateTime.FromOADate(0) : offset.UtcDateTime;
return $"CDATE({string.Format(CultureInfo.InvariantCulture, DateTimeFormatConst, dateTime)})";
}
}

@ -4902,7 +4902,7 @@ UnicodeDataTypes.StringUnicode ---> [nullable varchar] [MaxLength = 255]
if (entityType.FindProperty(nameof(BuiltInDataTypes.TestDateTimeOffset)) != null)
{
var param7 = new DateTimeOffset(new DateTime(), TimeSpan.FromHours(-8.0));
var param7 = new DateTimeOffset(new DateTime(), TimeSpan.FromHours(0.0));
Assert.Same(
entity,
set.Where(e => e.Id == 11 && EF.Property<DateTimeOffset>(e, nameof(BuiltInDataTypes.TestDateTimeOffset)) == param7)

@ -54,6 +54,7 @@ EntityFrameworkCore.Jet.FunctionalTests.BuiltInDataTypesJetTest.Can_insert_query
EntityFrameworkCore.Jet.FunctionalTests.BuiltInDataTypesJetTest.Can_perform_query_with_ansi_strings_test
EntityFrameworkCore.Jet.FunctionalTests.BuiltInDataTypesJetTest.Can_perform_query_with_max_length
EntityFrameworkCore.Jet.FunctionalTests.BuiltInDataTypesJetTest.Can_query_using_any_mapped_data_types_with_nulls
EntityFrameworkCore.Jet.FunctionalTests.BuiltInDataTypesJetTest.Can_query_using_any_nullable_data_type_as_literal
EntityFrameworkCore.Jet.FunctionalTests.BuiltInDataTypesJetTest.Can_query_using_DateDiffHour_using_TimeSpan
EntityFrameworkCore.Jet.FunctionalTests.BuiltInDataTypesJetTest.Can_query_using_DateDiffMinute_using_TimeSpan
EntityFrameworkCore.Jet.FunctionalTests.BuiltInDataTypesJetTest.Can_query_using_DateDiffSecond_using_TimeSpan
@ -14470,6 +14471,10 @@ EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindWhereQueryJetTest.Where_d
EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindWhereQueryJetTest.Where_datetime_utcnow(isAsync: True)
EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindWhereQueryJetTest.Where_datetime_year_component(isAsync: False)
EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindWhereQueryJetTest.Where_datetime_year_component(isAsync: True)
EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindWhereQueryJetTest.Where_datetimeoffset_now_component(isAsync: False)
EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindWhereQueryJetTest.Where_datetimeoffset_now_component(isAsync: True)
EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindWhereQueryJetTest.Where_datetimeoffset_utcnow_component(isAsync: False)
EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindWhereQueryJetTest.Where_datetimeoffset_utcnow_component(isAsync: True)
EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindWhereQueryJetTest.Where_de_morgan_and_optimized(isAsync: False)
EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindWhereQueryJetTest.Where_de_morgan_and_optimized(isAsync: True)
EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindWhereQueryJetTest.Where_de_morgan_or_optimized(isAsync: False)

@ -11072,8 +11072,12 @@ EntityFrameworkCore.Jet.FunctionalTests.Query.GearsOfWarQueryJetTest.Where_datet
EntityFrameworkCore.Jet.FunctionalTests.Query.GearsOfWarQueryJetTest.Where_datetimeoffset_minute_component(isAsync: True)
EntityFrameworkCore.Jet.FunctionalTests.Query.GearsOfWarQueryJetTest.Where_datetimeoffset_month_component(isAsync: False)
EntityFrameworkCore.Jet.FunctionalTests.Query.GearsOfWarQueryJetTest.Where_datetimeoffset_month_component(isAsync: True)
EntityFrameworkCore.Jet.FunctionalTests.Query.GearsOfWarQueryJetTest.Where_datetimeoffset_now(isAsync: False)
EntityFrameworkCore.Jet.FunctionalTests.Query.GearsOfWarQueryJetTest.Where_datetimeoffset_now(isAsync: True)
EntityFrameworkCore.Jet.FunctionalTests.Query.GearsOfWarQueryJetTest.Where_datetimeoffset_second_component(isAsync: False)
EntityFrameworkCore.Jet.FunctionalTests.Query.GearsOfWarQueryJetTest.Where_datetimeoffset_second_component(isAsync: True)
EntityFrameworkCore.Jet.FunctionalTests.Query.GearsOfWarQueryJetTest.Where_datetimeoffset_utcnow(isAsync: False)
EntityFrameworkCore.Jet.FunctionalTests.Query.GearsOfWarQueryJetTest.Where_datetimeoffset_utcnow(isAsync: True)
EntityFrameworkCore.Jet.FunctionalTests.Query.GearsOfWarQueryJetTest.Where_datetimeoffset_year_component(isAsync: False)
EntityFrameworkCore.Jet.FunctionalTests.Query.GearsOfWarQueryJetTest.Where_datetimeoffset_year_component(isAsync: True)
EntityFrameworkCore.Jet.FunctionalTests.Query.GearsOfWarQueryJetTest.Where_enum_has_flag_subquery_client_eval(isAsync: False)
@ -15664,6 +15668,12 @@ EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindWhereQueryJetTest.Where_d
EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindWhereQueryJetTest.Where_datetime_utcnow(isAsync: True)
EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindWhereQueryJetTest.Where_datetime_year_component(isAsync: False)
EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindWhereQueryJetTest.Where_datetime_year_component(isAsync: True)
EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindWhereQueryJetTest.Where_datetimeoffset_now_component(isAsync: False)
EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindWhereQueryJetTest.Where_datetimeoffset_now_component(isAsync: True)
EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindWhereQueryJetTest.Where_datetimeoffset_utcnow_component(isAsync: False)
EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindWhereQueryJetTest.Where_datetimeoffset_utcnow_component(isAsync: True)
EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindWhereQueryJetTest.Where_datetimeoffset_utcnow(async: False)
EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindWhereQueryJetTest.Where_datetimeoffset_utcnow(async: True)
EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindWhereQueryJetTest.Where_de_morgan_and_optimized(isAsync: False)
EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindWhereQueryJetTest.Where_de_morgan_and_optimized(isAsync: True)
EntityFrameworkCore.Jet.FunctionalTests.Query.NorthwindWhereQueryJetTest.Where_de_morgan_or_optimized(isAsync: False)
@ -17972,8 +17982,12 @@ EntityFrameworkCore.Jet.FunctionalTests.Query.TPCGearsOfWarQueryJetTest.Where_da
EntityFrameworkCore.Jet.FunctionalTests.Query.TPCGearsOfWarQueryJetTest.Where_datetimeoffset_minute_component(async: True)
EntityFrameworkCore.Jet.FunctionalTests.Query.TPCGearsOfWarQueryJetTest.Where_datetimeoffset_month_component(async: False)
EntityFrameworkCore.Jet.FunctionalTests.Query.TPCGearsOfWarQueryJetTest.Where_datetimeoffset_month_component(async: True)
EntityFrameworkCore.Jet.FunctionalTests.Query.TPCGearsOfWarQueryJetTest.Where_datetimeoffset_now(async: False)
EntityFrameworkCore.Jet.FunctionalTests.Query.TPCGearsOfWarQueryJetTest.Where_datetimeoffset_now(async: True)
EntityFrameworkCore.Jet.FunctionalTests.Query.TPCGearsOfWarQueryJetTest.Where_datetimeoffset_second_component(async: False)
EntityFrameworkCore.Jet.FunctionalTests.Query.TPCGearsOfWarQueryJetTest.Where_datetimeoffset_second_component(async: True)
EntityFrameworkCore.Jet.FunctionalTests.Query.TPCGearsOfWarQueryJetTest.Where_datetimeoffset_utcnow(async: False)
EntityFrameworkCore.Jet.FunctionalTests.Query.TPCGearsOfWarQueryJetTest.Where_datetimeoffset_utcnow(async: True)
EntityFrameworkCore.Jet.FunctionalTests.Query.TPCGearsOfWarQueryJetTest.Where_datetimeoffset_year_component(async: False)
EntityFrameworkCore.Jet.FunctionalTests.Query.TPCGearsOfWarQueryJetTest.Where_datetimeoffset_year_component(async: True)
EntityFrameworkCore.Jet.FunctionalTests.Query.TPCGearsOfWarQueryJetTest.Where_enum_has_flag_subquery_client_eval(async: False)
@ -19771,8 +19785,12 @@ EntityFrameworkCore.Jet.FunctionalTests.Query.TPTGearsOfWarQueryJetTest.Where_da
EntityFrameworkCore.Jet.FunctionalTests.Query.TPTGearsOfWarQueryJetTest.Where_datetimeoffset_minute_component(async: True)
EntityFrameworkCore.Jet.FunctionalTests.Query.TPTGearsOfWarQueryJetTest.Where_datetimeoffset_month_component(async: False)
EntityFrameworkCore.Jet.FunctionalTests.Query.TPTGearsOfWarQueryJetTest.Where_datetimeoffset_month_component(async: True)
EntityFrameworkCore.Jet.FunctionalTests.Query.TPTGearsOfWarQueryJetTest.Where_datetimeoffset_now(async: False)
EntityFrameworkCore.Jet.FunctionalTests.Query.TPTGearsOfWarQueryJetTest.Where_datetimeoffset_now(async: True)
EntityFrameworkCore.Jet.FunctionalTests.Query.TPTGearsOfWarQueryJetTest.Where_datetimeoffset_second_component(async: False)
EntityFrameworkCore.Jet.FunctionalTests.Query.TPTGearsOfWarQueryJetTest.Where_datetimeoffset_second_component(async: True)
EntityFrameworkCore.Jet.FunctionalTests.Query.TPTGearsOfWarQueryJetTest.Where_datetimeoffset_utcnow(async: False)
EntityFrameworkCore.Jet.FunctionalTests.Query.TPTGearsOfWarQueryJetTest.Where_datetimeoffset_utcnow(async: True)
EntityFrameworkCore.Jet.FunctionalTests.Query.TPTGearsOfWarQueryJetTest.Where_datetimeoffset_year_component(async: False)
EntityFrameworkCore.Jet.FunctionalTests.Query.TPTGearsOfWarQueryJetTest.Where_datetimeoffset_year_component(async: True)
EntityFrameworkCore.Jet.FunctionalTests.Query.TPTGearsOfWarQueryJetTest.Where_enum_has_flag_subquery_client_eval(async: False)

@ -2526,19 +2526,24 @@ WHERE `g`.`Discriminator` IN ('Gear', 'Officer')");
await base.Where_datetimeoffset_now(isAsync);
AssertSql(
$@"SELECT `m`.`Id`, `m`.`CodeName`, `m`.`Rating`, `m`.`Timeline`
"""
SELECT `m`.`Id`, `m`.`CodeName`, `m`.`Date`, `m`.`Duration`, `m`.`Rating`, `m`.`Time`, `m`.`Timeline`
FROM `Missions` AS `m`
WHERE (`m`.`Timeline` <> SYSDATETIMEOFFSET()) OR SYSDATETIMEOFFSET() IS NULL");
WHERE `m`.`Timeline` <> NOW()
""");
}
public override async Task Where_datetimeoffset_utcnow(bool isAsync)
{
var dtoffset = -1 * TimeZoneInfo.Local.BaseUtcOffset.TotalMinutes;
await base.Where_datetimeoffset_utcnow(isAsync);
AssertSql(
$@"SELECT `m`.`Id`, `m`.`CodeName`, `m`.`Rating`, `m`.`Timeline`
$"""
SELECT `m`.`Id`, `m`.`CodeName`, `m`.`Date`, `m`.`Duration`, `m`.`Rating`, `m`.`Time`, `m`.`Timeline`
FROM `Missions` AS `m`
WHERE (`m`.`Timeline` <> CAST(SYSUTCDATETIME() AS datetimeoffset)) OR SYSUTCDATETIME() IS NULL");
WHERE `m`.`Timeline` <> DATEADD('n', {dtoffset}.0, NOW())
""");
}
public override async Task Where_datetimeoffset_date_component(bool isAsync)

@ -787,6 +787,7 @@ WHERE MID(`c`.`City`, 1 + 1, 2) = 'ea'");
public override async Task Where_datetime_utcnow(bool isAsync)
{
var dtoffset = -1 * TimeZoneInfo.Local.BaseUtcOffset.TotalMinutes;
await base.Where_datetime_utcnow(isAsync);
AssertSql(
@ -795,21 +796,22 @@ WHERE MID(`c`.`City`, 1 + 1, 2) = 'ea'");
SELECT `c`.`CustomerID`, `c`.`Address`, `c`.`City`, `c`.`CompanyName`, `c`.`ContactName`, `c`.`ContactTitle`, `c`.`Country`, `c`.`Fax`, `c`.`Phone`, `c`.`PostalCode`, `c`.`Region`
FROM `Customers` AS `c`
WHERE NOW() <> CDATE({AssertSqlHelper.Parameter("@__myDatetime_0")})
WHERE DATEADD('n', {dtoffset}.0, NOW()) <> CDATE({AssertSqlHelper.Parameter("@__myDatetime_0")})
""");
}
public override async Task Where_datetimeoffset_utcnow(bool async)
{
var dtoffset = -1 * TimeZoneInfo.Local.BaseUtcOffset.TotalMinutes;
await base.Where_datetimeoffset_utcnow(async);
AssertSql(
"""
@__myDatetimeOffset_0='2015-04-10T00:00:00.0000000-08:00'
$"""
@__myDatetimeOffset_0='2015-04-10T08:00:00.0000000Z' (DbType = DateTime)
SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region]
FROM [Customers] AS [c]
WHERE CAST(SYSUTCDATETIME() AS datetimeoffset) <> @__myDatetimeOffset_0
SELECT `c`.`CustomerID`, `c`.`Address`, `c`.`City`, `c`.`CompanyName`, `c`.`ContactName`, `c`.`ContactTitle`, `c`.`Country`, `c`.`Fax`, `c`.`Phone`, `c`.`PostalCode`, `c`.`Region`
FROM `Customers` AS `c`
WHERE DATEADD('n', {dtoffset}.0, NOW()) <> @__myDatetimeOffset_0
""");
}
@ -935,19 +937,24 @@ WHERE DATEPART(millisecond, `o`.`OrderDate`) = 88");
await base.Where_datetimeoffset_now_component(isAsync);
AssertSql(
$@"SELECT `o`.`OrderID`, `o`.`CustomerID`, `o`.`EmployeeID`, `o`.`OrderDate`
"""
SELECT `o`.`OrderID`, `o`.`CustomerID`, `o`.`EmployeeID`, `o`.`OrderDate`
FROM `Orders` AS `o`
WHERE `o`.`OrderDate` = SYSDATETIMEOFFSET()");
WHERE `o`.`OrderDate` < NOW()
""");
}
public override async Task Where_datetimeoffset_utcnow_component(bool isAsync)
{
var dtoffset = -1 * TimeZoneInfo.Local.BaseUtcOffset.TotalMinutes;
await base.Where_datetimeoffset_utcnow_component(isAsync);
AssertSql(
$@"SELECT `o`.`OrderID`, `o`.`CustomerID`, `o`.`EmployeeID`, `o`.`OrderDate`
$"""
SELECT `o`.`OrderID`, `o`.`CustomerID`, `o`.`EmployeeID`, `o`.`OrderDate`
FROM `Orders` AS `o`
WHERE `o`.`OrderDate` = CAST(SYSUTCDATETIME() AS datetimeoffset)");
WHERE `o`.`OrderDate` <> DATEADD('n', {dtoffset}.0, NOW()) OR `o`.`OrderDate` IS NULL
""");
}
public override async Task Where_simple_reversed(bool isAsync)

@ -3691,22 +3691,23 @@ LEFT JOIN [Weapons] AS [w] ON [w].[SynergyWithId] IS NOT NULL
await base.Where_datetimeoffset_now(async);
AssertSql(
"""
SELECT [m].[Id], [m].[CodeName], [m].[Duration], [m].[Rating], [m].[Timeline]
FROM [Missions] AS [m]
WHERE [m].[Timeline] <> SYSDATETIMEOFFSET()
"""
SELECT `m`.`Id`, `m`.`CodeName`, `m`.`Date`, `m`.`Duration`, `m`.`Rating`, `m`.`Time`, `m`.`Timeline`
FROM `Missions` AS `m`
WHERE `m`.`Timeline` <> NOW()
""");
}
public override async Task Where_datetimeoffset_utcnow(bool async)
{
var dtoffset = -1 * TimeZoneInfo.Local.BaseUtcOffset.TotalMinutes;
await base.Where_datetimeoffset_utcnow(async);
AssertSql(
"""
SELECT [m].[Id], [m].[CodeName], [m].[Duration], [m].[Rating], [m].[Timeline]
FROM [Missions] AS [m]
WHERE [m].[Timeline] <> CAST(SYSUTCDATETIME() AS datetimeoffset)
$"""
SELECT `m`.`Id`, `m`.`CodeName`, `m`.`Date`, `m`.`Duration`, `m`.`Rating`, `m`.`Time`, `m`.`Timeline`
FROM `Missions` AS `m`
WHERE `m`.`Timeline` <> DATEADD('n', {dtoffset}.0, NOW())
""");
}

@ -2942,22 +2942,23 @@ LEFT JOIN [Weapons] AS [w] ON [w].[SynergyWithId] IS NOT NULL
await base.Where_datetimeoffset_now(async);
AssertSql(
"""
SELECT [m].[Id], [m].[CodeName], [m].[Duration], [m].[Rating], [m].[Timeline]
FROM [Missions] AS [m]
WHERE [m].[Timeline] <> SYSDATETIMEOFFSET()
"""
SELECT `m`.`Id`, `m`.`CodeName`, `m`.`Date`, `m`.`Duration`, `m`.`Rating`, `m`.`Time`, `m`.`Timeline`
FROM `Missions` AS `m`
WHERE `m`.`Timeline` <> NOW()
""");
}
public override async Task Where_datetimeoffset_utcnow(bool async)
{
var dtoffset = -1 * TimeZoneInfo.Local.BaseUtcOffset.TotalMinutes;
await base.Where_datetimeoffset_utcnow(async);
AssertSql(
"""
SELECT [m].[Id], [m].[CodeName], [m].[Duration], [m].[Rating], [m].[Timeline]
FROM [Missions] AS [m]
WHERE [m].[Timeline] <> CAST(SYSUTCDATETIME() AS datetimeoffset)
$"""
SELECT `m`.`Id`, `m`.`CodeName`, `m`.`Date`, `m`.`Duration`, `m`.`Rating`, `m`.`Time`, `m`.`Timeline`
FROM `Missions` AS `m`
WHERE `m`.`Timeline` <> DATEADD('n', {dtoffset}.0, NOW())
""");
}

Loading…
Cancel
Save