浏览器、时区、Chrome 67 错误(历史时区更改)

Posted

技术标签:

【中文标题】浏览器、时区、Chrome 67 错误(历史时区更改)【英文标题】:Browsers, time zones, Chrome 67 Error (historic timezone changes) 【发布时间】:2018-11-09 14:44:54 【问题描述】:

我已将 Chrome 更新到 67 版本。我收到日期错误

==============

Microsoft Edge 42.17134.1.0

new Date("1900-01-01T00:00:00").getTimezoneOffset() 

-180

new Date("2018-05-30T00:00:00").getTimezoneOffset()

-180

Microsoft Internet Explorer 11.48.17134.0

new Date("1900-01-01T00:00:00").getTimezoneOffset() 

-180


new Date("2018-05-30T00:00:00").getTimezoneOffset() 

-180

Mozilla Firefox 60.0.1

new Date("1900-01-01T00:00:00").getTimezoneOffset() 

-180

new Date("2018-05-30T00:00:00").getTimezoneOffset() 

-180

Chrome 67.0.3396.62

new Date("1900-01-01T00:00:00").getTimezoneOffset() 

-150

new Date("2018-05-30T00:00:00").getTimezoneOffset()

-180

=======================

Chrome 67 中为-150...

另一个例子(Chrome 67):

new Date("1900-01-01T00:00:00");

Mon Jan 01 1900 00:00:00 GMT+0230 (Moscow Standard Time)

=======================

在 Chrome 67 中,时区开始不正确(+0230,原为:+0300)

请告诉我?

我能做什么?

情况很重要!我必须重写的所有代码...

=======================

【问题讨论】:

如果您想进行准确的计算,历史日期、时间和时区非常复杂。他们今天仍然有点乱,但比以前简单得多。您不能指望 javascript 实现包含所有时区和地区的所有日期的所有偏移量(特别是在 javascript 中“区域设置”实际上是语言代码,而不是位置时)。如果需要,请使用具有基于位置(而不是语言)的准确偏移量的合适数据库的库,例如 IANA 时区数据库。.. RobG,谢谢!你能说一些带有合适数据库的库(在 javascript 中)吗? 对外部资源的请求不在此处讨论。您可以从 moment timezone 开始,它是 moment.js 的扩展并使用来自 IANA 时区数据库的数据。但是,我不知道对历史数据的支持有多远,也不知道它有多广泛或准确。 谢谢!我已经用 momentjs 修改了代码。我遇到了另一个问题。客户已了解时区。使用“1900-01-01T00:00:00+02:30”的客户端没有问题,但是来自服务器“1900-01-01T00:00:00+03:00”的日期有问题。变成 1899 年,减去 30 分钟!我该如何解决?我已经学习了使用 Chrome 67 的客户端,以及客户端如何与其他浏览器一起使用?对不起我的英语! @Alexey:这是一个单独的问题,您需要在一个新问题中提供更多背景信息。 RobG 和我已经解释了为什么您可能会看到不同的偏移量,尤其是很久以前的日期/时间值。这就是这个问题的意义所在。如果您想知道如何最好地处理这个问题,您需要提供有关您正在尝试做什么以及您拥有什么代码的更多信息。 【参考方案1】:

我将假设您在欧洲/莫斯科时区 - 考虑到您提供的输出,这似乎很可能。

在 1900 年,欧洲/莫斯科时区的偏移量为 +02:30:17,according to the IANA time zone database。据推测,Chrome 正在四舍五入到 02:30 以避免亚分钟偏移,但据我所知,它正在返回适当的数据。至少根据 IANA 数据库,俄罗斯的偏移量在 1919 年首次变为整数小时。

可以说您应该问为什么其他浏览器不这样做 - 但更有可能的是,您应该更改代码以不询问 1970 年之前的时区信息。IANA 数据库旨在提供从 Unix 时代开始的准确数据;之前的任何事情都是非常“尽力而为”的。来自theory file:

为每个此类位置记录 1970 年之前的时钟转换,因为大多数系统支持 1970 年之前的时间戳,如果在 1970 年之前的转换中省略数据条目,则可能会出现异常行为。然而,该数据库不适用于需要准确处理各地所有过去时间的应用程序,也不足以满足这些应用程序的需求,因为要记录 1970 年以前的民用计时的所有细节需要付出太多的努力和猜测。尽管数据库范围之外的一些信息被收集在与数据库一起分发的文件后台区域中,但该文件的可靠性较低并且不一定遵循数据库指南。

如果您没有在以前版本的 Chrome 中看到它,那么为什么您会在 Chrome 67 中看到它 - 我想知道 Chrome 是否刚刚开始捆绑 IANA 时区数据而不是使用操作系统数据。

【讨论】:

这种行为是由 ECMA 规范的最新变化及其实现决定的(到目前为止,这些变化似乎只在 Chrome 中实现)-来源:chromium-review.googlesource.com/c/v8/v8/+/572148【参考方案2】:

我在使用new Date("..") 时遇到了一些类似的问题;构造函数。 (也因为 Chrome 版本发生了变化)

来自MDN Date Reference 的注释:

注意:由于浏览器的差异和不一致,强烈建议不要使用 Date 构造函数(和 Date.parse,它们是等效的)解析日期字符串。仅按惯例支持 RFC 2822 格式字符串。对 ISO 8601 格式的支持的不同之处在于仅日期字符串(例如“1970-01-01”)被视为 UTC,而不是本地。

也许可以在您的代码中使用其他 Date 构造函数,例如:

 new Date(Date.UTC(96, 1, 2, 3, 4, 5));

【讨论】:

以上是关于浏览器、时区、Chrome 67 错误(历史时区更改)的主要内容,如果未能解决你的问题,请参考以下文章

有没有办法在 Chrome devtools 中更改您的时区?

JS:如何获取时区

如何检测chrome浏览器[重复]

Moment.js - 显示选定范围内关于用户时区的历史数据

时区是怎么划分的

Android 服务器响应时间变量的时区更改为设备位置的时区