new Date("0001-01-01T01:00:00Z")
-> Mon Jan 01 0001 02:50:16 GMT+0150 (Moscow Standard Time)
GMT错误:我的时区GMT+3000
,但日期创建了GMT+0150
答案 0 :(得分:1)
对于日期,您可以(并且应该以我的名义)以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时区概念存在之前那些日期的规则所定义的偏移量有关。
在您的应用程序中,它们可能没有意义,我不建议您使用0001年1月1日这样的日期作为示例。
示例:
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年以来(例如欧洲/莫斯科)发生了多次变化。的 为使它们正常工作而进行的更改也带来了报告 在这里。
答案 1 :(得分:1)
时区是偏移量加上日期范围。为了格式化日期,javascript想知道零年莫斯科的时区偏移量。这是很难获得的信息,可能并不准确!您以为您在问一些简单的问题,但这实际上是极端的。如果要使用日期对象表示持续时间,则应以纪元为起点。
答案 2 :(得分:1)
Pac0's answer是正确的(并且您应该接受该答案,因为它排在第一位,而不是第一位)。只是提供详细说明:
之前记录的时区历史记录中的日期在the time zone database中标记为LMT
-代表Local Mean Time。偏移量是根据城市的纬度和经度得出的,而不是根据当前的任何政治决心得出的。
由于显示的偏移量比UTC提前1:50:16
,因此我可以得出您的系统时区为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:50:16的LMT条目。
为什么说“莫斯科标准时间”-该字符串来自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
中继区,直到1991年。然后,使用诸如/common/main/en.xml
这样的语言文件之一作为英语,我们可以看到分配给该中继区的实际文本:
<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
。