Защо използването на JavaScript за планиране на Q1 година 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 ден (стандартното му поведение).


person conny    schedule 30.11.2010    source източник
comment
О, БОЖЕ МОЙ. Току-що свършихме да се тревожим за 2k бъговете - и вие измислихте КАКВО?! ... Голям +1 :)   -  person Martin Algesten    schedule 30.11.2010
comment
@Martin: О, имаме много по-належащ проблем, който да ни тревожи: en.wikipedia.org/wiki/ Година_2038_проблем   -  person T.J. Crowder    schedule 30.11.2010
comment
@T.J Crowder. да! Но аз харесвам този човек Кони. Той приема много сериозно бъдещата проверка на своите приложения.   -  person Martin Algesten    schedule 30.11.2010
comment
Дори 64-битови цели числа ще обвиват от неделя, 4 декември 292 277 026 596. Може дори да не се опитваме да поправим тези неща.   -  person Jimmy    schedule 30.11.2010


Отговори (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 GMT+0000 (GMT стандартно време)
Използване на стандартен конструктор: сряда, 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 в милисекунди от 01 януари 1970 г. UTC. Във времевите стойности високосните секунди се игнорират. Предполага се, че има точно 86 400 000 милисекунди на ден. Числовите стойности на ECMAScript могат да представляват всички цели числа от –9,007,199,254,740,991 до 9,007,199,254,740,991; този диапазон е достатъчен за измерване на времето с точност до милисекунди за всеки момент, който е в рамките на приблизително 285 616 години, напред или назад, от 01 януари 1970 г. UTC.

Но тъй като Safari изглежда се справя добре, когато не го помолите да излезе извън пистата, очевидно проблемът е в кода за анализиране на нестандартни низове.

person T.J. Crowder    schedule 30.11.2010
comment
Стига да не е в IE6, вероятно ще бъде поправен дотогава. Интересно, благодаря за насоките към спецификацията. - person conny; 01.12.2010
comment
Ще взема този отговор, не заради примерното форматиране, страхотния указател jsbin или факта, че в момента е единственият отговор, а заради препратката към ски на открито. Благодаря! - person conny; 04.01.2011
comment
@conny: LOL! Радвам се, че помогна и забавлява малко. Най-добри, - person T.J. Crowder; 04.01.2011