Почему использование JavaScript для планирования первого квартала 22034 года ненадежно в Safari?

Есть что-то подозрительное в вычислении дат далекого будущего, когда это делается на стороне браузера (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)

Мое чувство кишки говорит мне, что это похоже на ошибку високосного года. Но какой здесь шаблон игры, чем можно объяснить ошибку?


Редактировать:

Как насчет того, чтобы спросить 29 февраля?

d=new Date('29 Feb 22034')
Wed Mar 01 22034 00:00:00 GMT+0000 (GMT)

Это возвращает последний февраль + 1 день (его стандартное поведение).

1 ответ

Решение

Это потому, что формат даты вы даете new Date() это нестандартно. Факт, что вы что-то получаете, потому что Safari делает вам одолжение. (См. Раздел 15.9.1.15 спецификации для допустимых форматов; в основном упрощенный ISO-8601. И наличие какого-либо стандарта для разбора строк даты / времени является относительно новым [5-е издание].)

Если вы используете стандартный конструктор, например, new Date (22034, 2, 1) (месяцы начинаются с нуля, так что это 1 марта 22034 г.), он работает нормально. Вы можете проверить это так ( живая копия):

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

Что для меня с помощью Safari для Windows приводит к:

С нестандартной строкой: вт 28 февраля 22034 00:00:00 по Гринвичу + 0000 (стандартное время по Гринвичу)
Использование стандартного конструктора: ср. 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 спецификации:

Время измеряется в ECMAScript в миллисекундах с 1 января 1970 года по Гринвичу. В значениях времени високосные секунды игнорируются. Предполагается, что есть ровно 86 400 000 миллисекунд в день. Числовые значения ECMAScript могут представлять все целые числа от –9,007,199,254,740,991 до 9,007,199,254,740,991; этого диапазона достаточно для измерения времени с точностью до миллисекунды в любой момент времени, который находится в пределах приблизительно 285 616 лет, либо вперед, либо назад, с 1 января 1970 года по UTC.

Но, как кажется, Safari прекрасно справляется с этим, когда вы не просите его выходить из-под контроля, очевидно, проблема заключается в коде синтаксического анализа нестандартных строк.

Другие вопросы по тегам