JavaScriptSerializer使用DateTime或DateTimeOffset进行反序列化

时间:2017-09-21 21:47:47

标签: .net json datetime deserialization datetimeoffset

针对.NET4.5编译的VB2012:过去几天一直令人难以置信。我有json数据,我正在使用JavaScriptSerializer.Deserialize类进行解析。其中一个领域如下:

depart 2017-09-22T00:45:00-07:00

这是当地的出发时间(这是在洛杉矶)。

在我的包装类中,我写了

Public Class JsonLeg
    Public depart As DateTime
    Public blah...many more fields
End Class

我摄取json数据并使用JavaScriptSerializer.Deserialize来解析它。在此之后我调试输出,它看起来像这样

depart                 [Kind=Local] 2017-09-22T02:45:00
depart.ToLocalTime     [Kind=Local] 2017-09-22T02:45:00
depart.ToUniversalTime [Kind=Utc  ] 2017-09-22T07:45:00

看起来很好,但ToLocalTime只是将它转换为计算机在达拉斯的时区。我需要的是<2017> LA 2017-09-22T00:45:00 的当地时间与没有种类的日期列表进行比较。我如何取出原始位置的当地时间而不是计算机的当地时间?

我使用DateTimeOffset作为变量进行了测试,但我担心在解析json数据时我不明白解串器正在做什么。

该调试看起来像:

depart.DateTime      [Kind=Unspecified] 2017-09-22T00:45:00
depart.LocalDateTime [Kind=Local      ] 2017-09-22T02:45:00
depart.UtcDateTime   [Kind=Utc        ] 2017-09-22T07:45:00

在这种情况下,DateTimeOffset.DateTime为我提供了我需要的东西。但为什么?我试图了解差异是什么以及解串器如何解析每个差异。

1 个答案:

答案 0 :(得分:0)

您的数据采用ISO 8601扩展格式,并带有偏移量。 RFC3339也涵盖了这一点。

当您使用DateTime将此格式的字符串反序列化为JavaScriptSerializer时,它正在做出一个相当大的假设,即它是使用DateTime从另一个Kind=Local生成的。由于您的计算机与生成数据的计算机之间的偏移量可能匹配也可能不匹配,因此它首先应用提供的偏移量来获取UTC,然后将其转换回您当地的时区。这可能不是您想要的行为,并且没有一种非常好的方法可以使JavaScriptSerializer表现得与众不同。解析成DateTimeOffset更有意义。然后,生成的日期,时间和偏移部分完全匹配所提供的内容。

获得DateTimeOffset后,调用.DateTime可以返回日期和时间部分,结果为Unspecified。这是所有DateTimeOffset实例的标准行为,而不仅仅是通过解析的实例。原因是偏移量可能是任何值,将其映射到LocalUtc都会出错。

同样,.LocalDateTime转换为考虑偏移的本地时间(类似于直接解析为DateTime)。 .UtcDateTime将偏移量考虑在内并转换为UTC,就像您在.ToUniversalTime()版本上调用DateTime一样。

此外,您应该考虑使用Json.NET而不是JavaScriptSerializer。包括Microsoft在内的大多数.NET社区现在都使用此库进行JSON序列化。它更加灵活,并且在日期和时间方面倾向于开箱即用。