ISO 8601 日期 JS 解释差异 - IE/FF 与 Chrome
ISO 8601 Date JS Interpretation Difference - IE/FF versus Chrome
为什么 IE/FF 和 Chrome javascript 引擎 differ on how to interpret 这种 日期格式 (YYYY- MM-DDTHH:mm:ss.fff) 没有时区指示符?
new Date("2015-02-18T15:43:57.803").getUTCHours()
UTC 时间
Chrome: 15
IE11/FF: 21
我不明白 - 是因为 Chrome 假设它是本地的而 IE/FF 假设它是 UTC 吗?这似乎是一个 Chrome 错误。
有趣的是 - 在字符串末尾附加一个 "Z" 告诉 Chrome 和 IE/FF 时间是 UTC,他们可以同意。有没有其他人注意到 javascript 与 Date
的实施差异?
new Date("2015-02-18T15:43:57.803Z").getUTCHours()
UTC 时间
Chrome: 15
IE11/FF: 15
最终 - 这是 out-of-box serializer for ASP.NET Web API, which I thought used JSON.NET, but now appears to be internal where JSON.NET uses IsoDateTimeConverter
的结果。
检查 GlobalConfiguration.Configuration.Formatters.JsonFormatter
告诉我我们正在使用 JsonMediaTypeFormatter
。 Web API 不是开箱即用的 JSON.NET 序列化程序吗?
这对 Web API 人来说是一个福音 - 至少在 ASP.NET MVC 中我们有一个一致的日期格式(尽管是专有的 - /Date (刻度数)/)通过 JavascriptSerializer
ES5 says that ISO 8601 format dates without a time zone should be treated as local(that interpretation has since been revised), but the ed. 6 draft 表示将它们视为 UTC。一些脚本引擎已经实现了 ed。 6,部分ES5,其余都不是。
编辑。 6(及更高版本)不符合 ISO 8601 规范。
底线是不要使用 Date.parse(或将字符串传递给 Date 构造函数),手动解析日期字符串。
对我们来说,这个问题的症结在于 DateTimeStyles.RoundtripKind
仅在您的 DateTime
属性设置 DateTime.DateTimeKind
时有效( 不同于 DateTimeKind.Unspecified
- 默认 ) 或更好 - 使用 DateTimeOffset
其中 enforces use of the TimeZone specificity.
因为我们已经有了 DateTime
class 属性,我们现在通过从 DateTimeZoneHandling.RoundtripKind
分配 JsonSerializerSettings.DateTimeZoneHandling
来解决这个问题(DateTime default) 到 Global.asax.cs
中的 DateTimeZoneHandling.Utc
。这一更改实质上是将“Z”附加到 DateTime
的末尾 - 但是还有一个步骤可以将本地时间转换为 UTC。
第二步是通过分配 IsoDateTimeConverter.DateTimeStyles
which JSON.NET JsonSerializer
来提供偏移量,将从 SerializerSettings.Converters
获取并自动从本地时间转换为 UTC - 很像开箱即用的 ASP.NET MVC 确实如此。
显然 - 还有其他选择,但这是适合我们的解决方案。
Global.asax.cs
protected void Application_Start() {
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.DateTimeZoneHandling = Newtonsoft.Json.DateTimeZoneHandling.Utc;
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.Converters.Add(new IsoDateTimeConverter() { DateTimeStyles = DateTimeStyles.AdjustToUniversal });
}
DateTimeStyles.AdjustToUniversal
的 reason this works is because RoundtripKind
honors DateTime's DateTimeKind
- which is Unspecified
by default. We want to explicitly convert this to UTC - which JavaScriptSerializer
used to do for us out of the box for ASP.NET MVC. The regional offset is provided 将您的本地 DateTime
转换为 UTC。
为什么 IE/FF 和 Chrome javascript 引擎 differ on how to interpret 这种 日期格式 (YYYY- MM-DDTHH:mm:ss.fff) 没有时区指示符?
new Date("2015-02-18T15:43:57.803").getUTCHours()
UTC 时间
Chrome: 15
IE11/FF: 21
我不明白 - 是因为 Chrome 假设它是本地的而 IE/FF 假设它是 UTC 吗?这似乎是一个 Chrome 错误。
有趣的是 - 在字符串末尾附加一个 "Z" 告诉 Chrome 和 IE/FF 时间是 UTC,他们可以同意。有没有其他人注意到 javascript 与 Date
的实施差异?
new Date("2015-02-18T15:43:57.803Z").getUTCHours()
UTC 时间
Chrome: 15
IE11/FF: 15
最终 - 这是 out-of-box serializer for ASP.NET Web API, which I thought used JSON.NET, but now appears to be internal where JSON.NET uses IsoDateTimeConverter
的结果。
检查 GlobalConfiguration.Configuration.Formatters.JsonFormatter
告诉我我们正在使用 JsonMediaTypeFormatter
。 Web API 不是开箱即用的 JSON.NET 序列化程序吗?
这对 Web API 人来说是一个福音 - 至少在 ASP.NET MVC 中我们有一个一致的日期格式(尽管是专有的 - /Date (刻度数)/)通过 JavascriptSerializer
ES5 says that ISO 8601 format dates without a time zone should be treated as local(that interpretation has since been revised), but the ed. 6 draft 表示将它们视为 UTC。一些脚本引擎已经实现了 ed。 6,部分ES5,其余都不是。
编辑。 6(及更高版本)不符合 ISO 8601 规范。
底线是不要使用 Date.parse(或将字符串传递给 Date 构造函数),手动解析日期字符串。
对我们来说,这个问题的症结在于 DateTimeStyles.RoundtripKind
仅在您的 DateTime
属性设置 DateTime.DateTimeKind
时有效( 不同于 DateTimeKind.Unspecified
- 默认 ) 或更好 - 使用 DateTimeOffset
其中 enforces use of the TimeZone specificity.
因为我们已经有了 DateTime
class 属性,我们现在通过从 DateTimeZoneHandling.RoundtripKind
分配 JsonSerializerSettings.DateTimeZoneHandling
来解决这个问题(DateTime default) 到 Global.asax.cs
中的 DateTimeZoneHandling.Utc
。这一更改实质上是将“Z”附加到 DateTime
的末尾 - 但是还有一个步骤可以将本地时间转换为 UTC。
第二步是通过分配 IsoDateTimeConverter.DateTimeStyles
which JSON.NET JsonSerializer
来提供偏移量,将从 SerializerSettings.Converters
获取并自动从本地时间转换为 UTC - 很像开箱即用的 ASP.NET MVC 确实如此。
显然 - 还有其他选择,但这是适合我们的解决方案。
Global.asax.cs
protected void Application_Start() {
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.DateTimeZoneHandling = Newtonsoft.Json.DateTimeZoneHandling.Utc;
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.Converters.Add(new IsoDateTimeConverter() { DateTimeStyles = DateTimeStyles.AdjustToUniversal });
}
DateTimeStyles.AdjustToUniversal
的 reason this works is because RoundtripKind
honors DateTime's DateTimeKind
- which is Unspecified
by default. We want to explicitly convert this to UTC - which JavaScriptSerializer
used to do for us out of the box for ASP.NET MVC. The regional offset is provided 将您的本地 DateTime
转换为 UTC。