JSON.NET 将 +00:00 时区解析为当地时间,但 Z 解析为 UTC

Posted

技术标签:

【中文标题】JSON.NET 将 +00:00 时区解析为当地时间,但 Z 解析为 UTC【英文标题】:JSON.NET Parses +00:00 timezone as local times, but Z as UTC 【发布时间】:2015-07-28 23:14:13 【问题描述】:

我一直遇到 Web API 解析日期时间不正确的问题,我已追踪到 JSON.NET。

问题是,如果我发送这个日期时间:

2015-07-28T19:06:01.000+00:00

在 JSON PUT 请求中,在我的模型中解析的 DateTime 将转换为本地服务器时区中的时间,其中 C# datetime 类型是本地的,而不是 UTC。

如果我发送这个日期时间:

2015-07-28T19:06:01.000Z

它将正确地保持为 UTC,使用 C# datetime 类型的 UTC,这正是我想要的。

我可以通过像这样设置 DateTimeZoneHandling 来解决这个问题:

SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Utc;

但我不明白为什么它首先会这样做。根据 ISO8601,Z 和 +00:00 应该是同一个意思吧?我担心将 DateTimeZomeHandling 设置为全局 UTC,因为我可能不希望端点上的每个日期都被视为 UTC。

是否有其他设置可以告诉它考虑 +00:00 表示 UTC?

【问题讨论】:

【参考方案1】:

DateTime 仅区分 UTCLocal(和 Unknown)。考虑到两个不同的Local 时间当然可能是两个不同区域的本地时间,并且Local 时间确实可能是UTC 时间,如果它位于使用 UTC 的时区(例如冰岛全年,或冬天的爱尔兰)。因此,DateTime 可能是 Local,与 UTC 的时间差为零。

另一方面,ISO 8601(更明智)要么包括时区信息以及日期和/或时间,要么不包括。

两者之间没有完美的往返方式,因此考虑到Z 表示UTC+00:00 表示Local(但与UTC 相同的那种本地)是对此的不完美妥协通过提供DateTimeZoneHandling 使人们可以从这种妥协中进行调整,从而使情况变得不那么完美。

使用DateTimeOffset 代替DateTime 是另一种处理DateTime 与日期、时间和偏移量组合之间不匹配的方法。

【讨论】:

很好的解释!谢谢!当您概述妥协时,这是有道理的,我找不到任何关于此的 JSON.NET 文档 - 我猜他们可以方便地添加。所以我可以在我的模型中使用 DateTimeOffset 而不是设置我的 json 序列化程序设置,它应该保持在 UTC? 如果您使用DateTimeOffset,则该值的UtcDateTime 属性将始终为您提供UTC 时间(并且LocalDateTime 将始终位于代码运行的本地,如有必要进行转换)所以这是一种方法。如果有适合您需要的DateTimeZoneHandling 选项,它可能会比这更简单。如果您可能需要处理不同的时区并保留时区信息,那么只有 DateTimeOffset 会这样做。

以上是关于JSON.NET 将 +00:00 时区解析为当地时间,但 Z 解析为 UTC的主要内容,如果未能解决你的问题,请参考以下文章

iPhone:将格林威治标准时间转换为当地时间

Java:解析日期字符串,时区缩写为Date对象

将前导零附加到给定值[重复]

将时区设置为熊猫数据框

将时区从时间戳列转换为各种时区

将日期从 GMT 时区转换为本地时区——使用 ISO_OFFSET_DATE_TIME