为什么在 Safari 中使用 JavaScript 规划 22034 年第一季度不可靠?

发布于 2024-10-05 09:06:26 字数 681 浏览 7 评论 0原文

在浏览器端(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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

浪菊怪哟 2024-10-12 09:06:26

这是因为您为 new Date() 提供的日期格式是非标准的。事实上你能得到任何东西是因为 Safari 帮了你一个忙。 (有关有效格式,请参阅规范第 15.9.1.15 节;基本上是简化的 ISO-8601。并且具有解析日期/时间字符串的任何标准是相对较新的[第五版]。)

如果您使用标准构造函数,例如,new Date (22034, 2, 1) (月份从零开始,即 22034 年 3 月 1 日),效果很好。您可以像这样测试它(Live Copy):

display("With non-standard string: " + new Date("1 Mar 22034"));
display("Using standard constructor: " + new Date(22034, 2, 1));

对于我来说,使用 Windows 版 Safari 会导致:

使用非标准字符串:Tue Feb 28 22034 00:00:00 GMT+0000(GMT 标准时间)

使用标准构造函数:Wed Mar 01 22034 00:00:00 GMT+0000(GMT 标准时间)

如您所见,第一行显示错误的日期,而第二行显示正确的日期。

标准构造函数在 Chrome、Opera 和 Firefox(均在 Ubuntu 下)、IE6、IE7 和 IE8 中也能正常工作: http:// /jsbin.com/ogiqu

如果 Safari 确实无法处理该日期(而不是不解析您可靠地提供的非标准字符串),那么这将是一个令人惊讶的 Safari 特定错误。来自规范的第 15.9.1.1 节:

自 UTC 1970 年 1 月 1 日起,ECMAScript 中的时间以毫秒为单位进行测量。在时间值中闰秒
被忽略。假设每天恰好有 86,400,000 毫秒。 ECMAScript 数值
可以表示从 –9,007,199,254,740,991 到 9,007,199,254,740,991 的所有整数;这个范围足以
以毫秒精度测量大约 285,616 年内任何时刻的时间,或者
向前或向后,从 UTC 时间 1970 年 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):

display("With non-standard string: " + new Date("1 Mar 22034"));
display("Using standard constructor: " + new Date(22034, 2, 1));

Which for me using Safari for Windows results in:

With non-standard string: Tue Feb 28 22034 00:00:00 GMT+0000 (GMT Standard Time)

Using standard constructor: Wed Mar 01 22034 00:00:00 GMT+0000 (GMT Standard Time)

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:

Time is measured in ECMAScript in milliseconds since 01 January, 1970 UTC. In time values leap seconds
are ignored. It is assumed that there are exactly 86,400,000 milliseconds per day. ECMAScript Number values
can represent all integers from –9,007,199,254,740,991 to 9,007,199,254,740,991; this range suffices to
measure times to millisecond precision for any instant that is within approximately 285,616 years, either
forward or backward, from 01 January, 1970 UTC.

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文