javascript new Date() 构造函数对于相同不同格式字符串的不明确行为

Sha*_*man 2 javascript timezone datetime utc

我当地的时区是(UTC+06:00) Dhaka。在我自己的时区,我没有发现这个问题。但是将时区更改为(UTC -12:00) International Date Line West我的电脑,

new Date(["2014","01","01"])正在给我输出Wed Jan 01 2014 00:00:00 GMT-1200 (GMT-12:00)

new Date("2014-01-01")正在给我输出Tue Dec 31 2013 12:00:00 GMT-1200 (GMT-12:00)

为什么会发生这种情况?不应该["2014","01","01"]"2014-01-01"假设给出相同的输出吗?

Mat*_*int 5

一些东西:

  • 构造函数Date不接受数组。请参阅规范MDN 文档。任何此类津贴都是特定于实施的。例如,new Date(["2014","01","01"])将在 Chrome 中工作,因为 Chrome 作者决定允许它,但在 Edge 中它给出一个,Invalid Date因为规范不要求它。(这同样适用于Date.UTC(array)。)

  • 如果您有单独的日期部分,则应将它们直接传递到构造函数中。请注意,在这种形式的构造函数中,月份范围为 0 到 11,因此必须将第二个参数减一。

    new Date(2014, 0, 1)
    
    Run Code Online (Sandbox Code Playgroud)
  • 当您使用上述形式时,参数旨在以本地时间为单位——即为代码执行的环境设置的时区(浏览器环境中用户的时区,或服务器的时区)在 Node.js 环境中)。时间参数(小时、分钟、秒、毫秒)默认为0,因此这是本地时区的午夜,或者2014-01-01T00:00:00.000

  • 如果您打算传递基于 UTC 的参数,请使用该Date.UTC函数,并将结果传递回Date构造函数,如下所示:

    new Date(Date.UTC(2014, 0, 1))
    
    Run Code Online (Sandbox Code Playgroud)

    这将日期对象设置为午夜 UTC,或2014-01-01T00:00:00.000Z.

  • 当您将字符串传递给日期构造函数时,首先尝试根据规范中定义的规则对其进行解析。如果它不能被规范的规则解析,则可以以特定于实现的方式解析它。

    该规范定义格式YYYY-MM-DD(不带任何时间部分)的字符串将被解析为 UTC。这与 ISO-8601 不同,这就是为什么您在调用 时会看到不同的结果new Date("2014-01-01")。它被解释为好像您通过了2014-01-01T00:00:00.000Z(UTC)。

  • Date对象本身仅跟踪一个值,即自 Unix 纪元(UTC)以来的毫秒数1970-01-01T00:00:00.000Z.valueOf()您可以通过调用或来查看该值.getTime()。因此,当您使用任何被视为本地时间的形式进行解析时,解析时会发生从本地时间到 UTC 的转换。

  • 稍后,当您执行任何需要本地时间输出的操作时,例如调用.toString()或使用 、 等函数.getDate().getHours()则会执行从内部基于 UTC 的时间戳到本地时间的另一次转换。

  • console.log在某些环境中,当您使用对象时,您还会看到转换发生Date,就像您调用.toString(). 在其他情况下,您将看到基于 UTC 的输出,就像调用.toISOString(). 控制台输出是特定于实现的。