new Date("0001-01-01T01:00:00Z")
- > Mon Jan 01 0001 02:50:16 GMT+0150 (Moscow Standard Time)
不正确GMT:我的时区GMT+3000
,但日期创建GMT+0150
对于日期,你可以(也应该,在我看来)在UTC ISO定义它们8601 “Z” 格式( “YYYY-MM-DDTHH:MM:SSZ”),就像你一样。
但是,要获得这些日期的用户友好的字符串表示,这将取决于你的客户机上使用的Javascript引擎。您可以限制输出,如果你明确指定与toLocaleString()
参考时区。
var date = new Date("1990-01-01T01:00:00Z");
console.log(date.toLocaleString("en-US", {timeZone: "Asia/Jerusalem"}));
console.log(date.toLocaleString("en-US", {timeZone: "Europe/Moscow"}));
console.log(date.toLocaleString("en-US", {timeZone: "Africa/Djibouti"}));
// output on my machine, should be the same on yours :
// 1/1/1990, 3:00:00 AM
// 1/1/1990, 4:00:00 AM
// 1/1/1990, 4:00:00 AM
console.log(date.toString());
// output **on my machine**, should **not** be the same on yours
// Mon Jan 01 1990 02:00:00 GMT+0100 (Central European Standard Time)
对于16秒问题,这也与方式IANA时区的概念出现之前的那些日期由规则定义的偏移。
他们可能没有意义在应用程序中,我劝阻你使用日期像1月1日0001年对于你的例子。
例子 :
var date = new Date("0001-01-01T01:00:00Z");
console.log(date.toLocaleString("en-US", {timeZone: "Asia/Jerusalem"}));
console.log(date.toLocaleString("en-US", {timeZone: "Europe/Moscow"}));
console.log(date.toLocaleString("en-US", {timeZone: "Africa/Djibouti"}));
// output on my machine, should be the same on yours :
// 1/1/1, 3:20:54 AM
// 1/1/1, 3:30:17 AM
// 1/1/1, 3:27:16 AM
console.log(date.toString());
// output **on my machine**, should **not** be the same on yours
// Mon Jan 01 0001 01:09:21 GMT+0009 (Central European Standard Time)
这里更多的信息(感谢约翰·卡尔松的链接):
https://bugs.chromium.org/p/chromium/issues/detail?id=849404
从这个链接最相关的评论是,我认为:
这是工作的打算和按规格工作。细则中指出,我们必须遵循IANA时区数据库。
在1880年,有没有标准时区和美洲/洛杉矶时区偏移是基于它的经度。同样是其他时区也是如此。
还要注意的是有世界各地的许多时区的区偏移量(不论是否有DST或何时开始DST),即使自2000年以来多次更改(例如,欧洲/莫斯科)。这种变化使他们正常工作也带来了怎么在这里报道。
时区是偏移加上一个时间范围。要格式化你的约会,JavaScript的想知道什么时区偏移是莫斯科在这一年零。这是硬信息来通过,并且可能不准确!你以为你问简单的东西,但它实际上是非常极端的。如果要使用日期对象来表示持续时间,你应该采取划时代的起点。
Pac0's answer是正确的(你应该接受这个答案,因为它是先有没有这一项)。但只是提供一个详细的解释:
从时区的记录之前的历史日期标为the time zone database LMT
- 它代表Local Mean Time。偏移量是从城市的纬度和经度得出,而不是由任何当前的政治决心。
由于偏移显示的是1:50:16
比UTC的,我可以得出你的系统时区是Europe/Minsk
。这是看到in the tzdb sources here:
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Europe/Minsk 1:50:16 - LMT 1880
这仅仅是该区域条目Europe/Minsk
,它说,直到1880年,使用UTC + 1的LMT条目的第一行:50:16。
至于为什么它说:“莫斯科标准时间” - 该字符串来自Unicode CLDR数据,这在/common/supplemental/metaZones.xml
文件中,我们可以看到:
<timezone type="Europe/Minsk">
<usesMetazone to="1991-03-30 23:00" mzone="Moscow"/>
<usesMetazone to="2011-03-27 00:00" from="1991-03-30 23:00" mzone="Europe_Eastern"/>
<usesMetazone to="2014-10-26 22:00" from="2011-03-27 00:00" mzone="Europe_Further_Eastern"/>
<usesMetazone from="2014-10-26 22:00" mzone="Moscow"/>
</timezone>
所以Europe/Minsk
使用Moscow
metazone,直到1991年。然后,使用语言文件中的一个,如/common/main/en.xml
英语,我们可以看到分配给该metazone实际的文字:
<metazone type="Moscow">
<long>
<generic>Moscow Time</generic>
<standard>Moscow Standard Time</standard>
<daylight>Moscow Summer Time</daylight>
</long>
</metazone>
现在你有一个字符串Mon Jan 01 0001 02:50:16 GMT+0150 (Moscow Standard Time)
是如何从0001-01-01T01:00:00Z
得出一个完整的画面。