diff --git a/Microsoft.Azure.Cosmos/src/Linq/ExpressionToSQL.cs b/Microsoft.Azure.Cosmos/src/Linq/ExpressionToSQL.cs
index 3bbf936bce..4e3174895f 100644
--- a/Microsoft.Azure.Cosmos/src/Linq/ExpressionToSQL.cs
+++ b/Microsoft.Azure.Cosmos/src/Linq/ExpressionToSQL.cs
@@ -551,7 +551,7 @@ private static SqlScalarExpression ApplyCustomConverters(Expression left, SqlLit
else if (memberType == typeof(DateTime))
{
SqlStringLiteral serializedDateTime = (SqlStringLiteral)right.Literal;
- value = DateTime.Parse(serializedDateTime.Value);
+ value = DateTime.Parse(serializedDateTime.Value, provider: null, DateTimeStyles.RoundtripKind);
}
if (value != default(object))
diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/BaselineTest/TestBaseline/LinqTranslationBaselineTests.TestDateTimeJsonConverterTimezones.xml b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/BaselineTest/TestBaseline/LinqTranslationBaselineTests.TestDateTimeJsonConverterTimezones.xml
new file mode 100644
index 0000000000..6c3ceb9716
--- /dev/null
+++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/BaselineTest/TestBaseline/LinqTranslationBaselineTests.TestDateTimeJsonConverterTimezones.xml
@@ -0,0 +1,26 @@
+
+
+
+
+ (doc.IsoDateOnly == new DateTime(2016, 9, 13, 0, 0, 0, Local)))]]>
+
+
+
+
+
+
+ (doc.IsoDateOnly == new DateTime(2016, 9, 13, 0, 0, 0, Utc)))]]>
+
+
+
+
\ No newline at end of file
diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/LinqTranslationBaselineTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/LinqTranslationBaselineTests.cs
index a3b62a1ff1..d25f213868 100644
--- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/LinqTranslationBaselineTests.cs
+++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/LinqTranslationBaselineTests.cs
@@ -11,6 +11,7 @@ namespace Microsoft.Azure.Cosmos.Services.Management.Tests.LinqProviderTests
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
+ using System.Globalization;
using System.Linq;
using Newtonsoft.Json.Converters;
using BaselineTest;
@@ -134,6 +135,9 @@ internal class DataObject : LinqTestObject
[JsonConverter(typeof(IsoDateTimeConverter))]
public DateTime IsoTime;
+ [JsonConverter(typeof(DateJsonConverter))]
+ public DateTime IsoDateOnly;
+
// This field should serialize as ISO Date
// as this is the default DateTimeConverter
// used by Newtonsoft
@@ -145,6 +149,21 @@ internal class DataObject : LinqTestObject
public string Pk;
}
+ class DateJsonConverter : IsoDateTimeConverter
+ {
+ public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+ {
+ if (value is DateTime dateTime)
+ {
+ writer.WriteValue(dateTime.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture));
+ }
+ else
+ {
+ base.WriteJson(writer, value, serializer);
+ }
+ }
+ }
+
internal class AmbientContextObject
{
public double FieldAccess;
@@ -350,6 +369,30 @@ public void TestDateTimeJsonConverter()
this.ExecuteTestSuite(inputs);
}
+ [TestMethod]
+ public void TestDateTimeJsonConverterTimezones()
+ {
+ const int Records = 10;
+ DateTime midDateTime = new (2016, 9, 13, 0, 0, 0);
+ Func createDataObj = (random) =>
+ {
+ DataObject obj = new() {
+ IsoDateOnly = LinqTestsCommon.RandomDateTime(random, midDateTime),
+ Id = Guid.NewGuid().ToString(),
+ Pk = "Test"
+ };
+ return obj;
+ };
+ Func> getQuery = LinqTestsCommon.GenerateTestCosmosData(createDataObj, Records, testContainer);
+
+ List inputs = new()
+ {
+ new LinqTestInput("IsoDateTimeConverter LocalTime = filter", b => getQuery(b).Where(doc => doc.IsoDateOnly == new DateTime(2016, 9, 13, 0, 0, 0, DateTimeKind.Local))),
+ new LinqTestInput("IsoDateTimeConverter UniversalTime = filter", b => getQuery(b).Where(doc => doc.IsoDateOnly == new DateTime(2016, 9, 13, 0, 0, 0, DateTimeKind.Utc))),
+ };
+ this.ExecuteTestSuite(inputs);
+ }
+
[TestMethod]
public void TestNullableFields()
{
diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Microsoft.Azure.Cosmos.EmulatorTests.csproj b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Microsoft.Azure.Cosmos.EmulatorTests.csproj
index 5e69fbb1e0..24f2bc44bc 100644
--- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Microsoft.Azure.Cosmos.EmulatorTests.csproj
+++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Microsoft.Azure.Cosmos.EmulatorTests.csproj
@@ -34,6 +34,7 @@
+
@@ -189,6 +190,9 @@
PreserveNewest
+
+ PreserveNewest
+
PreserveNewest
diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Linq/CosmosLinqJsonConverterTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Linq/CosmosLinqJsonConverterTests.cs
new file mode 100644
index 0000000000..e4f90f1957
--- /dev/null
+++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Linq/CosmosLinqJsonConverterTests.cs
@@ -0,0 +1,54 @@
+//------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//------------------------------------------------------------
+
+namespace Microsoft.Azure.Cosmos.Linq
+{
+ using System;
+ using System.Globalization;
+ using System.Linq.Expressions;
+ using Microsoft.VisualStudio.TestTools.UnitTesting;
+ using Newtonsoft.Json;
+ using Newtonsoft.Json.Converters;
+
+ [TestClass]
+ public class CosmosLinqJsonConverterTests
+ {
+ [TestMethod]
+ public void DateTimeKindIsPreservedTest()
+ {
+ // Should work for UTC time
+ DateTime utcDate = new DateTime(2022, 5, 26, 0, 0, 0, DateTimeKind.Utc);
+ Expression> expr = a => a.StartDate <= utcDate;
+ string sql = SqlTranslator.TranslateExpression(expr.Body);
+ Assert.AreEqual("(a[\"StartDate\"] <= \"2022-05-26\")", sql);
+
+ // Should work for local time
+ DateTime localDate = new DateTime(2022, 5, 26, 0, 0, 0, DateTimeKind.Local);
+ expr = a => a.StartDate <= localDate;
+ sql = SqlTranslator.TranslateExpression(expr.Body);
+ Assert.AreEqual("(a[\"StartDate\"] <= \"2022-05-26\")", sql);
+ }
+
+ class TestDocument
+ {
+ [JsonConverter(typeof(DateJsonConverter))]
+ public DateTime StartDate { get; set; }
+ }
+
+ class DateJsonConverter : IsoDateTimeConverter
+ {
+ public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+ {
+ if (value is DateTime dateTime)
+ {
+ writer.WriteValue(dateTime.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture));
+ }
+ else
+ {
+ base.WriteJson(writer, value, serializer);
+ }
+ }
+ }
+ }
+}