diff --git a/src/Redis.OM/Modeling/JsonDiff.cs b/src/Redis.OM/Modeling/JsonDiff.cs index df17e34d..39949241 100644 --- a/src/Redis.OM/Modeling/JsonDiff.cs +++ b/src/Redis.OM/Modeling/JsonDiff.cs @@ -1,4 +1,7 @@ -using System.Web; +using System; +using System.Linq; +using System.Text.Json; +using System.Web; using Newtonsoft.Json.Linq; namespace Redis.OM.Modeling @@ -35,8 +38,25 @@ public string[] SerializeScriptArgs() { JTokenType.String => new[] { _operation, _path, $"\"{HttpUtility.JavaScriptStringEncode(_value.ToString())}\"" }, JTokenType.Boolean => new[] { _operation, _path, _value.ToString().ToLower() }, + JTokenType.Date => SerializeAsDateTime(), _ => new[] { _operation, _path, _value.ToString() } }; } + + private string[] SerializeAsDateTime() + { + var jValue = (JValue)_value; + if (jValue.Value is DateTimeOffset) + { + return new[] + { + _operation, + _path, + $"{JsonSerializer.Serialize(_value.Value())}", + }; + } + + return new[] { _operation, _path, $"{JsonSerializer.Serialize(_value.Value())}" }; + } } } diff --git a/src/Redis.OM/Modeling/RedisCollectionStateManager.cs b/src/Redis.OM/Modeling/RedisCollectionStateManager.cs index 3b7291d1..f4ec792e 100644 --- a/src/Redis.OM/Modeling/RedisCollectionStateManager.cs +++ b/src/Redis.OM/Modeling/RedisCollectionStateManager.cs @@ -104,7 +104,7 @@ internal bool TryDetectDifferencesSingle(string key, object value, out IList(dataJson, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); + var current = JsonConvert.DeserializeObject(dataJson, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore, DateFormatHandling = DateFormatHandling.IsoDateFormat, DateParseHandling = DateParseHandling.DateTimeOffset, DateTimeZoneHandling = DateTimeZoneHandling.Utc }); var snapshot = (JToken)Snapshot[key]; var diff = FindDiff(current!, snapshot); differences = BuildJsonDifference(diff, "$", snapshot); diff --git a/test/Redis.OM.Unit.Tests/RediSearchTests/SearchFunctionalTests.cs b/test/Redis.OM.Unit.Tests/RediSearchTests/SearchFunctionalTests.cs index 6d16a86a..3b720a14 100644 --- a/test/Redis.OM.Unit.Tests/RediSearchTests/SearchFunctionalTests.cs +++ b/test/Redis.OM.Unit.Tests/RediSearchTests/SearchFunctionalTests.cs @@ -1113,5 +1113,25 @@ public void TestSelectOnEmbeddedDocuments() Assert.Equal("World",resNoNew.InnerInnerCascade.Tag); Assert.Equal(42,resNoNew.InnerInnerCascade.Num); } + + [Fact] + public void SaveDateTimeOffset() + { + var obj = new ObjectWithDateTimeOffsetJson + { + Offset = DateTimeOffset.Now, + DateTime = DateTime.Now + }; + var collection = new RedisCollection(_connection); + collection.Insert(obj); + + var intermediate = collection.First(x => x.Id == obj.Id); + intermediate.Offset = intermediate.Offset.AddMinutes(10); + intermediate.DateTime = intermediate.DateTime.AddHours(1); + collection.Update(intermediate); + var final = collection.First(x => x.Id == obj.Id); + Assert.Equal(intermediate.Offset,final.Offset); + Assert.Equal(intermediate.DateTime,final.DateTime); + } } } \ No newline at end of file diff --git a/test/Redis.OM.Unit.Tests/RedisSetupCollection.cs b/test/Redis.OM.Unit.Tests/RedisSetupCollection.cs index 94c57e7c..2e533f2a 100644 --- a/test/Redis.OM.Unit.Tests/RedisSetupCollection.cs +++ b/test/Redis.OM.Unit.Tests/RedisSetupCollection.cs @@ -29,6 +29,7 @@ public RedisSetup() Connection.CreateIndex(typeof(ComplexObjectWithCascadeAndJsonPath)); Connection.CreateIndex(typeof(BasicJsonObjectTestSave)); Connection.CreateIndex(typeof(SelectTestObject)); + Connection.CreateIndex(typeof(ObjectWithDateTimeOffsetJson)); } private IRedisConnection _connection = null; @@ -66,6 +67,7 @@ public void Dispose() Connection.DropIndexAndAssociatedRecords(typeof(ComplexObjectWithCascadeAndJsonPath)); Connection.DropIndexAndAssociatedRecords(typeof(BasicJsonObjectTestSave)); Connection.DropIndexAndAssociatedRecords(typeof(SelectTestObject)); + Connection.DropIndexAndAssociatedRecords(typeof(ObjectWithDateTimeOffsetJson)); } } } diff --git a/test/Redis.OM.Unit.Tests/Serialization/ObjectWithDateTimeOffset.cs b/test/Redis.OM.Unit.Tests/Serialization/ObjectWithDateTimeOffset.cs index a42adbe5..61f215b1 100644 --- a/test/Redis.OM.Unit.Tests/Serialization/ObjectWithDateTimeOffset.cs +++ b/test/Redis.OM.Unit.Tests/Serialization/ObjectWithDateTimeOffset.cs @@ -8,4 +8,15 @@ public class ObjectWithDateTimeOffset { public DateTimeOffset Offset { get; set; } } + + [Document(StorageType = StorageType.Json)] + public class ObjectWithDateTimeOffsetJson + { + [Indexed] + [RedisIdField] + public string Id { get; set; } + + public DateTimeOffset Offset { get; set; } + public DateTime DateTime { get; set; } + } } \ No newline at end of file