【问题标题】:JSON serialization of .NET DateTime round trip doesn't work.NET DateTime 往返的 JSON 序列化不起作用
【发布时间】:2012-11-04 08:27:02
【问题描述】:

如果我使用 System.Web.Script.Serialization.JavaScriptSerializer 保存 .NET DateTime,则反序列化版本与原始版本相差一个小时。任何想法为什么?

编辑:我的工作站的时区是 UTC。

下面是一个 NUnit 测试;请注意,断言仅在添加一个小时后才有效。

    [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)); // !!
    }

【问题讨论】:

  • 为什么您的示例代码费心将其写入磁盘?只需记住反序列化的字符串引用...
  • (顺便说一句,我非常怀疑您的工作站的时区是否真的是 UTC。我怀疑它是英国时区,冬天是 UTC,但夏天是 UTC+1 - 和日期你给的是夏天。)
  • @JonSkeet,迟来的:回复:你的第二条评论,如果你想把它作为答案发布,我会给你信用。 JSON 序列化并没有保留所有的 DateTime 状态以及夏令时。回复:第 1 项,示例代码是一个未完全简化的较大单元测试版本,其中问题已具体化。
  • 我已将其添加到答案的底部。

标签: .net json


【解决方案1】:

序列化程序显然将其转换为 instant 时间,以自 unix 纪元以来的毫秒数形式。换句话说,它实际上是先调用ToUniversalTime()

此时,有关DateTime 的原始“种类”的任何信息都将丢失。

在反序列化时,结果始终是 UTC 类型的 DateTime

如果您开始DateTime 和某种 UTC,您将往返。如果您还需要记住该类型,则需要单独保存该数据。请记住,当地时间本来就很模糊。

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);
    }
}

输出:

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

当然,这只是突出problems with DateTime being conceptually broken to start with...

编辑:另外,正如 cmets 所述,顺便说一下,我非常怀疑您工作站的时区是否真的是 UTC。我怀疑这是英国时区,冬天是 UTC,但夏天是 UTC+1 - 你给的日期是夏天。

【讨论】:

    【解决方案2】:

    请改用JsonConvert.DeserializeObject。它保留正确的日期时间

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-01-05
      • 1970-01-01
      • 2013-05-22
      • 2013-05-18
      • 2012-06-09
      • 1970-01-01
      • 1970-01-01
      • 2013-02-06
      相关资源
      最近更新 更多