为什么在 Safari 中使用 JavaScript 规划 22034 年第一季度不可靠?
在浏览器端(Safari 5.0.1)将字符串传递到 Date() 构造函数中计算远期日期时,有一些可疑之处:
我将其范围缩小到二月到三月的过渡在 22034 年:
d = new Date('1 Mar 22034')
Tue Feb 28 22034 00:00:00 GMT+0000 (GMT)
任何以后的日期,构造函数总是返回一个相差一天的 Date 对象!
那么更早的日期呢?二月的最后一天看起来不错:
d=new Date('28 Feb 22034')
Tue Feb 28 22034 00:00:00 GMT+0000 (GMT)
我的直觉告诉我,这看起来像是与闰年相关的错误。但这里的模式是什么,这个错误的解释是什么?
编辑:
如果我们要求 2 月 29 日怎么样?
d=new Date('29 Feb 22034')
Wed Mar 01 22034 00:00:00 GMT+0000 (GMT)
这将返回 2 月的最后一天 + 1 天(其标准行为)。
There is something fishy about the calculation of far future dates when done on the browser side (Safari 5.0.1), passing strings into the Date() constructor:
I narrowed it down to the February-March transition in year 22034:
d = new Date('1 Mar 22034')
Tue Feb 28 22034 00:00:00 GMT+0000 (GMT)
Feeding it any later date, the constructor always returns a Date object off-by-one day!
What about earlier dates? The last day in February looks good:
d=new Date('28 Feb 22034')
Tue Feb 28 22034 00:00:00 GMT+0000 (GMT)
My gut-feeling tells me that looks like a leap-year related bug. But what is the pattern in play here, what could be the explanation of the bug?
Edit:
How about if we ask for February 29th?
d=new Date('29 Feb 22034')
Wed Mar 01 22034 00:00:00 GMT+0000 (GMT)
That returns the last of Feb + 1 day (its standard behavior).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这是因为您为
new Date()
提供的日期格式是非标准的。事实上你能得到任何东西是因为 Safari 帮了你一个忙。 (有关有效格式,请参阅规范第 15.9.1.15 节;基本上是简化的 ISO-8601。并且具有解析日期/时间字符串的任何标准是相对较新的[第五版]。)如果您使用标准构造函数,例如,
new Date (22034, 2, 1)
(月份从零开始,即 22034 年 3 月 1 日),效果很好。您可以像这样测试它(Live Copy):对于我来说,使用 Windows 版 Safari 会导致:
如您所见,第一行显示错误的日期,而第二行显示正确的日期。
标准构造函数在 Chrome、Opera 和 Firefox(均在 Ubuntu 下)、IE6、IE7 和 IE8 中也能正常工作: http:// /jsbin.com/ogiqu
如果 Safari 确实无法处理该日期(而不是不解析您可靠地提供的非标准字符串),那么这将是一个令人惊讶的 Safari 特定错误。来自规范的第 15.9.1.1 节:
但当你不要求它离开滑雪道时,Safari 似乎可以很好地处理它,显然问题出在非标准字符串的解析代码中。
It's because the date format you're giving
new Date()
is non-standard. The fact you're getting anything is because Safari is doing you a favor. (See section 15.9.1.15 of the spec for valid formats; basically a simplified ISO-8601. And having any standard for parsing date/time strings is relatively new [5th edition].)If you use a standard constructor, e.g.,
new Date (22034, 2, 1)
(months start at zero, so that's March 1, 22034), it works fine. You can test it like this (live copy):Which for me using Safari for Windows results in:
As you can see, the first line shows the incorrect date, while the second line shows the correct one.
The standard constructor also works correctly in Chrome, Opera, and Firefox (all under Ubuntu), IE6, IE7, and IE8: http://jsbin.com/ogiqu
If it were really true that Safari couldn't handle that date (as opposed to not parsing the non-standard string you gave it reliably), it would be a surprising Safari-specific bug. From section 15.9.1.1 of the spec:
But as Safari seems to handle it fine when you don't ask it to go off-piste, apparently the problem is in the parsing code for non-standard strings.