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

时间:2012-11-15 17:06:00

标签: .net json

如果我使用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)); // !!
    }

2 个答案:

答案 0 :(得分:6)

串行器显然会及时将其转换为 instant ,其形式为自unix时代以来的毫秒数。换句话说,它首先有效地调用ToUniversalTime()

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

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

如果以<{1}}开始并使用某种UTC,那么您将进行往返。如果您还需要记住这种类型,则需要单独保存这些数据。请记住,当地时间本身可能含糊不清。

DateTime

输出:

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

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

编辑:另外,正如评论中所述,我非常怀疑你的工作站的时区是否真的是UTC。我怀疑它是英国时区,冬天是UTC,夏天是UTC + 1 - 而且你给的日期是夏天。

答案 1 :(得分:0)

使用JsonConvert.DeserializeObject代替。它保留了正确的DateTime