Newtonsoft.json: IsoDateTimeConverter - 始终附加 Z 或显式时区,以避免浏览器不兼容

创建于 2013-12-13  ·  5评论  ·  资料来源: JamesNK/Newtonsoft.Json

由于ES5.1 中的一个问题,浏览器对缺少尾的 ISO-8601 日期

目前,在序列化没有 DateTimeKind.UTC 参数创建的 DateTime 对象时,IsoDateTimeConverter 不会设置“Z”:

var date = new DateTime(2009, 2, 15, 0, 0, 0, DateTimeKind.Local);
var settings = new JsonSerializerSettings();
settings.Converters.Add(new IsoDateTimeConverter());

// Succeeds
Assert.IsTrue(JsonConvert.SerializeObject(date.ToUniversalTime(), settings).EndsWith("Z\""));

// Fails
Assert.IsTrue(JsonConvert.SerializeObject(date, settings).EndsWith("Z\""));

为了更轻松地处理来自 Json.NET 的输出,在 IsoDateTimeConverter 中将日期转换为字符串时,应始终附加“Z”(或设置显式时区)。

最简单的解决方法是在序列化每个日期对象时使用.ToUniversalTime()的结果(如上所示)。

最有用的评论

我被这个抛弃了,因为文档页面显示它确实附加了一个尾随 Z:

http://www.newtonsoft.com/json/help/html/DatesInJSON.htm

显示:"Details":"Application started.","LogDate":"2009-02-15T00:00:00Z" ... 但实际输出并非如此 - 它没有尾随 Z。我能够通过在序列化程序设置中设置此选项,在不调用 ToUniversalTime 的情况下获取 Z:

_jsonSettings.DateTimeZoneHandling = DateTimeZoneHandling.Utc;

可能只是文档问题。

所有5条评论

这是一个微妙的突破性变化,会刺痛很多依赖当前行为的人。 如果您想更改 DateTime 序列化,我建议您创建自己的 JsonConverter。

我同意这不是一个 JSON.Net 问题,但不必处理它会很好。 将它添加为一个可选的、不间断的特性如何(也许是 IsoDateTimeConverter 上的一个标志?)我浪费了时间研究这个依赖于浏览器的实现细节,而更多的时间用于弄清楚在使用 JSON.Net 时如何解决它。

此外,让浏览器误解您的 DateTime 是一种很容易被忽视的错误。 人们可能会在不知情的情况下遇到此错误。 将此作为一项功能公开给他们提供了了解它的机会和绕过它的方法。

我刚刚注意到这个问题。 不管不改变实现,它至少应该在文档中。

取自http://en.wikipedia.org/wiki/ISO_8601#Time_zone_designators

“ISO 8601 中的时区表示为本地时间(未指定位置)、UTC 或与 UTC 的偏移量。

如果没有给出带有时间表示的 UTC 关系信息,则假定时间为本地时间。 虽然在同一时区进行通信时假设本地时间可能是安全的,但在跨不同时区进行通信时使用它是模棱两可的。 通常最好使用标准的符号来指示时区(区域指示符)。”

我被这个抛弃了,因为文档页面显示它确实附加了一个尾随 Z:

http://www.newtonsoft.com/json/help/html/DatesInJSON.htm

显示:"Details":"Application started.","LogDate":"2009-02-15T00:00:00Z" ... 但实际输出并非如此 - 它没有尾随 Z。我能够通过在序列化程序设置中设置此选项,在不调用 ToUniversalTime 的情况下获取 Z:

_jsonSettings.DateTimeZoneHandling = DateTimeZoneHandling.Utc;

可能只是文档问题。

@grennis ,文档可能不清楚但不正确。 它并不是说它总是附加一个 Z,而是说它使用 ISO 格式。 也就是说,Z 表示 UTC 日期,但并非所有日期都是 UTC。

它后来指出:

将 DateTimeZoneHandling 设置为 Utc 以将所有日期时间序列化为 UTC 日期

这意味着非 UTC 日期不会被序列化为 UTC 日期。 :)

此页面是否有帮助?
0 / 5 - 0 等级