[英]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.