c# – json.net datetime的序列化/反序列化’未指定’
发布时间:2020-12-15 08:00:05 所属栏目:百科 来源:网络整理
导读:在常规的.net中, 如果我们有一个DateTimeKind.Unspecified的时间 如果我们转换ToLocal – 它假定转换时输入日期是UTC. 如果我们转换为ToUniversal – 它假定转换时输入日期是本地的 但是,在JSON.Net中,如果我们在JSON.Net中的字符串日期未指定,它似乎没有这
在常规的.net中,
如果我们有一个DateTimeKind.Unspecified的时间 如果我们转换ToLocal – 它假定转换时输入日期是UTC. 如果我们转换为ToUniversal – 它假定转换时输入日期是本地的 但是,在JSON.Net中,如果我们在JSON.Net中的字符串日期未指定,它似乎没有这个逻辑?看看我下面的测试用例 – 我做错了吗?或者这是设计?或JSON.Net中的错误? // TODO: This Fails with output // date string: "2014-06-02T21:00:00.0000000" // date serialized: 2014-06-02T21:00:00.0000000Z // Expected date and time to be <2014-06-03 04:00:00>,but found <2014-06-02 21:00:00>. [TestMethod] public void NEW_Should_deserialize_unspecified_datestring_to_utc_date() { string dateString = ""2014-06-02T21:00:00.0000000""; DateTime dateRaw = new DateTime(2014,6,2,21,DateTimeKind.Unspecified); DateTime dateRawAsUtc = new DateTime(2014,3,4,DateTimeKind.Utc); dateRawAsUtc.Should().Be(dateRaw.ToUniversalTime()); JsonSerializerSettings settings = new JsonSerializerSettings(); settings.DateTimeZoneHandling = DateTimeZoneHandling.Utc; settings.DateFormatHandling = DateFormatHandling.IsoDateFormat; DateTime dateSerialized = JsonConvert.DeserializeObject<DateTime>(dateString,settings); Console.WriteLine("date string: " + dateString); Console.WriteLine("date serialized: " + dateSerialized.ToString("o")); dateSerialized.Kind.Should().Be(DateTimeKind.Utc); dateSerialized.Should().Be(dateRaw.ToUniversalTime()); dateSerialized.Should().Be(dateRawAsUtc); } // TODO: This Fails with output // date string: "2014-06-02T21:00:00.0000000" // date serialized: 2014-06-02T21:00:00.0000000-07:00 // Expected date and time to be <2014-06-02 14:00:00>,but found <2014-06-02 21:00:00>. [TestMethod] public void NEW_Should_deserialize_unspecified_datestring_to_local_date() { string dateString = ""2014-06-02T21:00:00.0000000""; DateTime dateRaw = new DateTime(2014,DateTimeKind.Unspecified); DateTime dateRawAsLocal = new DateTime(2014,14,DateTimeKind.Local); dateRawAsLocal.Should().Be(dateRaw.ToLocalTime()); JsonSerializerSettings settings = new JsonSerializerSettings(); settings.DateTimeZoneHandling = DateTimeZoneHandling.Local; settings.DateFormatHandling = DateFormatHandling.IsoDateFormat; DateTime dateSerialized = JsonConvert.DeserializeObject<DateTime>(dateString,settings); Console.WriteLine("date string: " + dateString); Console.WriteLine("date serialized: " + dateSerialized.ToString("o")); dateSerialized.Kind.Should().Be(DateTimeKind.Local); dateSerialized.Should().Be(dateRaw.ToLocalTime()); dateSerialized.Should().Be(dateRawAsLocal); } [TestMethod] public void NEW_Should_deserialize_unspecified_datestring_to_unspecified_date() { string dateString = ""2014-06-02T21:00:00.0000000""; // unspecified,does not have the 'Z' DateTime dateRaw = new DateTime(2014,DateTimeKind.Unspecified); JsonSerializerSettings settings = new JsonSerializerSettings(); settings.DateTimeZoneHandling = DateTimeZoneHandling.Unspecified; settings.DateFormatHandling = DateFormatHandling.IsoDateFormat; DateTime dateSerialized = JsonConvert.DeserializeObject<DateTime>(dateString,settings); Console.WriteLine("date string: " + dateString); Console.WriteLine("date serialized: " + dateSerialized.ToString("o")); dateSerialized.Kind.Should().Be(DateTimeKind.Unspecified); dateSerialized.Should().Be(dateRaw); } 解决方法
我不是百分百肯定你在这里寻找什么,但我认为假设JSON.Net在没有一点帮助的情况下满足你的所有需求是不安全的.如
Mr. Newton says:
首先要确定是否要支持接受未指定的日期,或者是否要假设所有传入的日期都是通用的,即使它们缺少尾随的Z. 如果您假设所有传入日期都是通用的,您可以看看它们是否有尾随Z,如果没有,则添加它(不完全是生产代码,但您明白了): if (!dateString.EndsWith("Z"",StringComparison.InvariantCultureIgnoreCase)) { dateString = dateString.Substring(0,dateString.LastIndexOf(""",StringComparison.InvariantCultureIgnoreCase)) + "Z""; } 假设的这种变化确实要求将您测试的日期修改为Utc. 如果您不想假定传入日期是通用的,而是将它们视为未指定,则需要通过替换来更改转换传入JSON的方式: JsonSerializerSettings settings = new JsonSerializerSettings(); settings.DateTimeZoneHandling = DateTimeZoneHandling.Utc; settings.DateFormatHandling = DateFormatHandling.IsoDateFormat; DateTime dateSerialized = JsonConvert.DeserializeObject<DateTime>(dateString,settings); 有: var oConverter = new Newtonsoft.Json.Converters.IsoDateTimeConverter(); DateTime dateSerialized = JsonConvert.DeserializeObject<DateTime>(dateString,oConverter); 这将导致一个未指定的日期与dateString完全匹配.这是你的助手发挥作用的地方: if (dateSerialized.Kind == DateTimeKind.Unspecified) { dateSerialized = dateSerialized.ToUniversalTime(); } 这意味着完整的,修订的第一个测试将如下所示,它将通过: string dateString = ""2014-06-02T21:00:00.0000000""; DateTime dateRaw = new DateTime(2014,DateTimeKind.Unspecified); DateTime dateRawAsUtc = new DateTime(2014,DateTimeKind.Utc); dateRawAsUtc.Should().Be(dateRaw.ToUniversalTime()); var oConverter = new Newtonsoft.Json.Converters.IsoDateTimeConverter(); DateTime dateSerialized = JsonConvert.DeserializeObject<DateTime>(dateString,oConverter); if (dateSerialized.Kind == DateTimeKind.Unspecified) { dateSerialized = dateSerialized.ToUniversalTime(); } Console.WriteLine("date string: " + dateString); Console.WriteLine("date serialized: " + dateSerialized.ToString("o")); dateSerialized.Kind.Should().Be(DateTimeKind.Utc); dateSerialized.Should().Be(dateRaw.ToUniversalTime()); dateSerialized.Should().Be(dateRawAsUtc); (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |