通过iso``0001-01-01T01:00:00''创建日期加上16秒

时间:2019-01-31 13:25:43

标签: javascript datetime timezone-offset

new Date("0001-01-01T01:00:00Z")-> Mon Jan 01 0001 02:50:16 GMT+0150 (Moscow Standard Time)
GMT错误:我的时区GMT+3000,但日期创建了GMT+0150

3 个答案:

答案 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