2012-04-22 75 views
18

首先,我认为时区可能与此有关。我在EST/EDT。另外,我在铬17/linux上测试这个。日期构造函数:数字参数与字符串参数在某些情况下给出不同的日期

现在,让我们说我创建了两个日期是这样的:

// December 5 

dateFromNumbers = new Date(2020, 11, 5); 
dateFromString = new Date("2020-12-5"); 

看来这些日期应具有相同的时间戳,和他们做:

+dateFromNumbers == +dateFromString; // true 

...至少在这种情况下, 。但在某些情况下,它们不会:

// December 15 

dateFromNumbers = new Date(2020, 11, 15); 
dateFromString = new Date("2020-12-15"); 

+dateFromNumbers == +dateFromString; // false 

这是怎么回事?

dateFromNumbers; // Tue Dec 15 2020 00:00:00 GMT-0500 (EST) 
dateFromString; // Mon Dec 14 2020 19:00:00 GMT-0500 (EST) 

貌似dateFromString为5小时早于在这种情况下dateFromNumbers(EST是GMT - 5,我敢肯定,它以某种方式有关)。

它似乎影响十月到十二月的结束。这里有一个小提琴,可以很容易地看出哪些日子不同(除非你是红绿色的色盲,在这种情况下,可能很难看到,我的道歉)。

http://jsfiddle.net/9gBfX/

什么给?


注:

  • 您可以设置系统时区到EST/EDT看到的jsfiddle例子,因为我看到它。
  • 日期的月份数量为零; 11不是拼写错误。
  • 这个问题出现在我检查的每一年。
+1

在您的第二个案件日期是2020年11月15日和2020年12月15日。是否是错字? – Habib 2012-04-22 16:03:49

+0

运行Chrome 18.0.1025.162 m,Windows,GMT +2:结果可重现。但明确指定字符串表示中的时间可以解决问题。我通常从字符串中避免日期,因为跨浏览器的格式支持是多种多样的,文档记录很差,毫秒更加可靠。 – DCoder 2012-04-22 16:23:47

回答

6

在寻找V8's source code后:

// Specification: 
// Accept ES5 ISO 8601 date-time-strings or legacy dates compatible 
// with Safari. 
<...> 
// A string that matches both formats (e.g. 1970-01-01) will be 
// parsed as an ES5 date-time string - which means it will default 
// to UTC time-zone. That's unavoidable if following the ES5 
// specification. 

读周围的代码,似乎既月份和日期2个符号长一个时间串被认为是有效的ES5时间串。在ES5解析器再往下,它解析日期和时间后,有一个评论:

// Successfully parsed ES5 Date Time String. Default to UTC if no TZ given. 

在“YYYY-MM-DD”的情况下,一旦代码获得迄今为止,ES5解析器成功解析整个字符串,因此它在遗留分析程序有机会本地化时区之前返回。否则(月/日是一个符号长)它被视为“遗留”日期时间,遗留分析器可以处理它并进行本地化。

2

使用“ - ”作为美国日期的日期分隔符会混淆某些浏览器,有些会执行日期算术,其他人会返回NaN,因此请使用“/”日期分隔符。文化感知解决方案是使用date.js,它是一个杰出的JavaScript日期处理程序,可解决您指出的问题(http://www.datejs.com/)。使用解析方法去除所有的困惑:

Date.parse("2020-12-15").toString() // yields the correct date ("Tue Dec 15 00:00:00 PST 2020"). 
+2

尝试使用“/”而不是“ - ”。 – 2012-04-22 16:28:37

+0

GGG在回答我的答案时是正确的。我应该详细阐述,现在已经这样做了。 – 2012-04-22 16:50:41

+0

虽然我没有降低它。 – 2012-04-22 16:50:56

2

中继上this post,似乎Date的字符串参数的构造函数是实现敏感,由于各种Date.parse()实现通过浏览器。

您的测量结果是正确的,如果您希望浏览器正确解析EST,您应该完全避免使用此构造函数。

2

它看起来像日期构造函数需要空格而不是' - '。它是推荐的方式。查核此链接:
3.3. Date and Time Specification

虽然foldingwhite空间在整个的日期 - 时间 规范允许的,则建议一个单一的空间中 该FWS出现(它是必需的还是可选的每个地方使用)

还检查了此链接:
https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Date

dateString:表示日期的字符串值。该字符串应采用解析方法识别的 格式(符合IETF RFC 2822 时间戳)。

我尝试下面的代码,它

dateFromNumbers = new Date(2020, 11, 15); 
dateFromString = new Date("2020 12 15"); 
alert(+dateFromNumbers == +dateFromString);​ 

而且它不是一个问题,十月份开始返回true,它做的两位数个月。如果我尝试同样的方法与9月份则:

dateFromNumbers = new Date(2020, 8, 15); 
dateFromString = new Date("2020-09-15"); 
alert(+dateFromNumbers == +dateFromString);​ // This returns false 

但是,如果使用单个数字九月则返回true

dateFromNumbers = new Date(2020, 8, 15); 
dateFromString = new Date("2020-9-15"); 
alert(+dateFromNumbers == +dateFromString);​ // This returns true 

如果以两位数利用空间九月,则返回true

dateFromNumbers = new Date(2020, 8, 15); 
dateFromString = new Date("2020 09 15"); 
alert(+dateFromNumbers == +dateFromString);​//This returns true 
3

下面是来自其他答案的简化答案。

日期识别不同的字符串格式

  • 非标准日期
  • RFC 2282日期
  • ES 5日期

大多数格式都被解释为当地日期

RFC 2282的第14页上,我们看到:

日期和时间应该表示当地时间。

非标准日期以类似的方式处理。

ES 5格式被解释为UTC

在ES 5规范我们看到的section 15.9.1.15

缺席时区偏移的值是“Z”。

“Z”代表UTC时间。

ES第十5个日期格式要求两位数的月份和日期。原始帖子中的月份和日期不是零填充的。 “2020-9-9”不是有效的ES 5日期表示;这是一种非标准的格式,所以它在当地时间被解释。 “2020-10-10”有效的ES 5日期表示,所以它必须用UTC解释。

可能的解决方法

  • 不要使用字符串构造/ Date.parse!
  • 更改分隔符以使格式不匹配ES 5格式。
  • 指定时区。
  • 将日期调整为当地时间。如果他们有几小时或几分钟:date.setMinutes(date.getTimezoneOffset());(无论如何,这似乎工作)。
相关问题