简体   繁体   English

.NET DateTime往返的JSON序列化不起作用

[英]JSON serialization of .NET DateTime round trip doesn't work

If I save a .NET DateTime using System.Web.Script.Serialization.JavaScriptSerializer the deserialized version is an hour different than the original version. 如果我使用System.Web.Script.Serialization.JavaScriptSerializer保存.NET DateTime,则反序列化版本与原始版本会相差一个小时。 Any ideas why? 有什么想法吗?

EDIT: My workstation's time zone is UTC. 编辑:我的工作站的时区为UTC。

A NUnit test is below; NUnit测试如下: note that the assertion works only after adding an hour. 请注意,该断言仅在添加一个小时后才有效。

    [Test]
    public void JsonSerializationOfDateTimesDoesntWork()
    {
        var originalDateTime = new DateTime(2011, 6, 20, 6, 5, 4, 3);
        const string fileName = "C:\\temp\\testDateTime.json";
        using (var writer = new StreamWriter(fileName, false))
        {
            writer.Write(new JavaScriptSerializer().Serialize(originalDateTime));
        }
        DateTime newDateTime;
        using (var reader = new StreamReader(fileName, false))
        {
            var readToEnd = reader.ReadToEnd();
            newDateTime = new JavaScriptSerializer().Deserialize<DateTime>(readToEnd);
        }

        Assert.AreEqual(originalDateTime, newDateTime.AddHours(1)); // !!
    }

The serializer apparently converts it to an instant in time, in the form of milliseconds since the unix epoch. 显然,串行器将其转换为即时时间,以unix纪元以来的毫秒为单位。 In other words, it's effectively calling ToUniversalTime() first. 换句话说,它实际上是ToUniversalTime()调用ToUniversalTime()

At that point, any information about the original "kind" of DateTime is lost. 到那时,有关DateTime原始“种类”的任何信息都将丢失。

On deserialization, the result is always a DateTime of kind UTC. 反序列化时,结果始终是UTC类型的DateTime

If you start with a DateTime with a kind of UTC, you'll round-trip. 如果带有某种UTC的DateTime 开始 ,则将进行往返。 If you need to remember the kind as well, you'll need to keep that data separately. 如果您还需要记住种类,则需要单独保存这些数据。 Just remember that local times can be inherently ambiguous. 请记住,当地时间可能固有地模棱两可。

using System;
using System.Web.Script.Serialization;

class Test
{
    public static void Main(string[] args)
    {
        var original = new DateTime(2011, 6, 20, 6, 5, 4, 3, DateTimeKind.Utc);
        var serializer = new JavaScriptSerializer();
        var text = serializer.Serialize(original);
        var parsed = serializer.Deserialize<DateTime>(text);
        Console.WriteLine("Original: {0} ({1})", original, original.Kind);
        Console.WriteLine("Text: {0}", text);
        Console.WriteLine("Parsed: {0} ({1})", parsed, parsed.Kind);
    }
}

Output: 输出:

Original: 20/06/2011 06:05:04 (Utc)
Text: "\/Date(1308549904003)\/"
Parsed: 20/06/2011 06:05:04 (Utc)

Of course, this just highlights the problems with DateTime being conceptually broken to start with ... 当然,这只是突出显示了DateTime从概念上开始就被破坏问题

EDIT: Also, as noted in comments, I very much doubt that your workstation's time zone is really UTC, by the way. 编辑:另外,如评论中所述,顺便说一句,我非常怀疑您工作站的时区确实是UTC。 I suspect it's the UK time zone, which is UTC in winter, but UTC+1 in summer - and the date you've given is in summer. 我怀疑这是英国时区,冬天是UTC,夏天是UTC + 1,而您指定的日期是夏天。

use JsonConvert.DeserializeObject instead. 使用JsonConvert.DeserializeObject代替。 It preserves the correct DateTime 它保留正确的DateTime

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM