特别是在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格式。