特别是在Node v8.9.0中。

考虑以下几行:

console.log(new Date("2006"));
console.log(new Date("2006 "));

他们产生以下输出:
2006-01-01T00:00:00.000Z
2006-01-01T08:00:00.000Z

请注意,第二行具有8小时时区偏移量。

为什么存在或不存在尾随空格都会导致创建日期时带/不带时区偏移?

最佳答案

摘要:空格的存在会导致日期解析器将日期解释为另一种格式,而当字符串中没有时区说明时,该格式将对时区使用不同的假设。
Date()构造函数或Date.parse()的一个复杂之处在于,对于不完整或部分日期的字符串,解析器试图猜测该字符串应被解释为ISO 8601 format还是RFC2822 format的简化形式。如果认为格式为ISO 8601并且未指定时区,则将采用UTC时区。如果认为格式为RFC2822,则将采用本地计算机时区。

因此,对于您的两个字符串,第一个字符串显然被假定为ISO 8601,因此使用了UTC时区假设,第二个字符串显然被假定为使用本地时区的RFC2822。

支持的ISO 8601格式不包含空格,而RFC2822格式可以包含一些空格,因此字符串中仅存在空格似乎会使解析器选择使用本地时区的RFC2822格式。

您可以阅读有关in the Date.parse() doc on MDN的一些信息。

作为引用,下面是一段简化的ISO 8601格式:

   Year:
      YYYY (eg 1997)
   Year and month:
      YYYY-MM (eg 1997-07)
   Complete date:
      YYYY-MM-DD (eg 1997-07-16)
   Complete date plus hours and minutes:
      YYYY-MM-DDThh:mmTZD (eg 1997-07-16T19:20+01:00)
   Complete date plus hours, minutes and seconds:
      YYYY-MM-DDThh:mm:ssTZD (eg 1997-07-16T19:20:30+01:00)
   Complete date plus hours, minutes, seconds and a decimal fraction of a
second
      YYYY-MM-DDThh:mm:ss.sTZD (eg 1997-07-16T19:20:30.45+01:00)
where:

     YYYY = four-digit year
     MM   = two-digit month (01=January, etc.)
     DD   = two-digit day of month (01 through 31)
     hh   = two digits of hour (00 through 23) (am/pm NOT allowed)
     mm   = two digits of minute (00 through 59)
     ss   = two digits of second (00 through 59)
     s    = one or more digits representing a decimal fraction of a second
     TZD  = time zone designator (Z or +hh:mm or -hh:mm)
     T    = a literal T separating the time

您会看到此格式没有空格。

RFC2822 format包含将日期/时间的不同部分分隔开的空格。完整的语法在链接的RFC中,但是在下面的示例中,您可以看到空格:
Mon, 25 Dec 1995 13:30:00 GMT

请注意,ES2015 spec for Date.parse() 描述了simplified ISO 8601 date format。当您提供与该格式不完全匹配的任何字符串时,您可能会遇到某些依赖于实现的解析行为。引用ES2015规范:



其中引用的“日期时间字符串格式”是简化的ISO 8601格式。

10-04 15:10
查看更多