JavaScript日期怪癖

时间:2018-01-23 19:11:02

标签: javascript datetime

这是我在JavaScript中目睹的最奇怪的行为。

在非常具体的情况下,此代码将产生40分28秒的时间:

var jsDate = new Date('01/01/1900 11:00:00');
jsDate.setSeconds(0);
var dateString = jsDate.toLocaleTimeString("en", {
    hour12 : false
});
alert(dateString); //dateString will be 10:19:32

这种情况发生在荷兰的一个网站上,但不适用于那里的开发者。它发生在Firefox和Chrome上。工作站是Windows 7。

测试它,我发现破碎的结果发生在1942年之前的任何一年。 1943年和1944年,它增加了一个小时。

每年之后,无论日期格式如何,都可以正常运行:01/01/19001900-01-01

好奇的背景:

我们有一个日期时间小部件,只对时间部分感兴趣。

修复是将虚拟日期设置为2000.但我们对"为什么"。

感到困惑。

Link to jsFiddle

此问题与UTC与本地化时间无关。最奇怪的功能是它可以用几分钟和几秒来改变时间,而不是几小时。

1 个答案:

答案 0 :(得分:3)

我会坚持回到10:19:32的荷兰示例,并解决为什么这个问题的一部分。

Europe/Amsterdam的{​​{3}}条目为time zone database,如下所示:

# Zone NAME            GMTOFF   RULES   FORMAT       [UNTIL]
Zone Europe/Amsterdam  0:19:32  -       LMT          1835
                       0:19:32  Neth    %s           1937 Jul  1
                       0:20     Neth    +0020/+0120  1940 May 16  0:00
                       1:00     C-Eur   CE%sT        1945 Apr  2  2:00
                       1:00     Neth    CE%sT        1977
                       1:00     EU      CE%sT

由于您在1900年通过了日期,因此第二行适用,其与UTC的偏移量为0:19:32,恰好与其上方的本地平均时间(LMT)条目重合。

Chris Pearce在here中解释道:

  

......这一切都发生在一个尚未采用标准时间的国家。荷兰争论是否应该使用GMT并将时钟转回大约20分钟或使用GMT + 1并向前走40分钟。无法达成协议,所以在所有其他欧洲国家都转移到标准时间之后很久就停留在当地时间。阿姆斯特丹首都城市的当地平均时间,格林威治标准时间+0:19:32,已在全国范围内使用了数十年,这已成为法定时间......

关于其他时区,您可能会打击他们自己有趣的历史记录,或者仅仅是TZDB中的本地平均时间条目,这通常是最早的条目,并且在没有其他时间历史时使用了解该地区的计时。

这里的教训是,时区是一个相对现代的发明,并且经常成为政治争议的焦点。不要认为,因为你知道他们今天如何工作,你的知识将适用于过去。还要记住,随着历史的各种花絮被发现,TZDB会相应更新,所以历史可以改变!

一般来说,在1970年之前的任何日期都会遇到奇怪的事情。

至于为什么你没有在每个浏览器中得到相同的结果,请参阅我的旧帖博客The Great Daylight Saving Time Controversy,其中包括ECMAScript 5.1和之前要求的TZ / DST规则忽略计时历史并假设当前规则始终存在。这已在ECMAScript 6和ECMA国际化API中修复 - 因此大多数现代浏览器将为您提供正确的结果。

但是,它还取决于他们从何处获取时区数据。 Windows计算机没有tzdb的完整历史记录,除非浏览器附带自己的副本。使用ICU进行此功能的浏览器运送他们自己的TZDB副本,因此那些将拥有历史数据,但不是每个浏览器都这样做。