Почему Javascript getYear () возвращает 108?

95

Почему этот javascript возвращает 108 вместо 2008? он получает правильный день и месяц, но не год?

myDate = new Date();
year = myDate.getYear();

год = 108?

ctrlShiftBryan
источник
29
О, грехи, которые мы совершили, пытаясь пройти через 2000 год.
DGentry
3
year = myDate.getFullYear() % 100;
Эндрю Ларссон

Ответы:

128

Это проблема 2000 года , учитываются только годы с 1900 года.

Теперь есть потенциальные проблемы совместимости, которые getYear()устарели в пользу getFullYear()- from quirksmode :

Чтобы сделать вопрос еще более сложным, date.getYear () в настоящее время устарела, и вы должны использовать date.getFullYear (), который, в свою очередь, не поддерживается старыми браузерами. Однако, если он работает, он всегда должен указывать полный год, т.е. 2000 вместо 100.

Ваш браузер дает следующие годы с помощью этих двух методов:

* The year according to getYear(): 108
* The year according to getFullYear(): 2008

Существуют также различия в реализации между Internet Explorer и Firefox, поскольку реализация IE getYear()была изменена, чтобы вести себя как getFullYear()- от IBM :

Согласно спецификации ECMAScript, getYear возвращает год минус 1900, первоначально предназначенный для возврата «98» за 1998 год. GetYear был объявлен устаревшим в ECMAScript версии 3 и заменен на getFullYear ().

Internet Explorer изменил getYear (), чтобы он работал как getFullYear () и сделал его совместимым с Y2k, в то время как Mozilla сохранила стандартное поведение.

ConroyP
источник
25

Поскольку getFullYear не работает в старых браузерах, вы можете использовать что-то вроде этого:

Date.prototype.getRealYear = function() 
{ 
    if(this.getFullYear)
        return this.getFullYear();
    else
        return this.getYear() + 1900; 
};

Прототип Javascript можно использовать для расширения существующих объектов, как и методы расширения C #. Теперь мы можем просто сделать это;

var myDate = new Date();
myDate.getRealYear();
// Outputs 2008
FlySwat
источник
7
Может быть, что-то вроде Date.prototype.getRealYear = Date.prototype.getFullYear? Date.prototype.getFullYear: function () {return this.getYear () + 1900; };
Валентин Голев
12

Проверьте документы. Это не проблема 2000 года - это проблема отсутствия проблемы 2000 года! Это решение было изначально принято на C и было скопировано в Perl, по-видимому, в JavaScript и, возможно, в несколько других языков. Давным-давно, по-видимому, все еще было желательно использовать двузначные числа, но, что удивительно, тот, кто разработал этот интерфейс, имел достаточно предусмотрительности, чтобы понять, что им нужно подумать о том, что произойдет в 2000 году и позже, поэтому вместо того, чтобы просто предоставить последние два цифр, они предоставили количество лет, прошедших с 1900 года. Вы можете использовать две цифры, если спешите или хотите пойти на риск. Или, если вы хотите, чтобы ваша программа продолжала работать, вы можете добавить к результату 100 и использовать полноценные четырехзначные годы.

Я помню, как впервые сделал манипуляции с датами в Perl. Как ни странно, я читал документы . Видимо это не обычное дело. Год или два спустя 31 декабря 1999 года меня вызвали в офис, чтобы исправить ошибку, обнаруженную в последнюю минуту в каком-то контрактном коде Perl, с которым я никогда не имел ничего общего. Это была именно та проблема: стандартный вызов даты возвращал годы с 1900 года, а программисты считали это годом двузначным числом. (Они предполагали, что в 2000 году получат «00».) Как молодой неопытный программист, я просто поразился тому, что мы так много заплатили за «профессиональную» работу, и эти люди даже не удосужились прочитать документация. Это было началом многих лет разочарования; теперь я стар и циничен. :)

В 2000 году ежегодная конференция YAPC Perl называлась «YAPC 19100» в честь этой часто сообщаемой не-ошибки.

В настоящее время, по крайней мере, в мире Perl, имеет больше смысла использовать стандартный модуль для обработки даты, который использует реальные четырехзначные числа. Не уверен, что может быть доступно для JavaScript.

скифоппи
источник
1
хе-хе ... напоминает мне карикатуру Дилберта ... "Вы читали историю про испанца по имени Мануал?" ;)
Адип Гупта
Я считаю, что @skiphoppy означало, что добавление 1900 к getYear () дало бы желаемый полный год. Это похоже на добавление +1 к getMonth () при получении удобочитаемого числа месяца. Пример: var ts = new Date (); var fullYear = (ts.getYear () + 1900); Но использование getFullYear () предпочтительнее. Пример: var fullYear = new Date (). GetFullYear ();
recurse
6

Он должен возвращать количество лет, прошедших с 1900 года.

Джереми Рутен
источник
4

использовать date.getFullYear().

Это (как правильно указано в другом месте) проблема 2000 года. Netscape (написанный до 2000 года) первоначально вернулся, например, 98из getYear(). Вместо того, чтобы вернуться 00, он вернулся 100в 2000 году. Затем появились другие браузеры, которые сделали это по-другому, и все были недовольны, поскольку царила несовместимость.

Более поздние браузеры поддерживали getFullYearстандартный метод для возврата полного года.

Дэн
источник
3

Этот вопрос настолько старый, что заставляет меня плакать от ностальгии по дням доткомов!

Правильно, Date.getYear () возвращает количество лет, прошедших с 1900 года, точно так же, как Perl localtime (). Возникает вопрос, почему язык, разработанный в 1990-х, не учитывал смену века, но что я могу сказать? Вы должны были там быть. В то время это имело своего рода смысл (как и pets.com).

До 2000 года можно было соблазнить исправить эту ошибку, добавив «19» к результату getYear (), что привело бы к «ошибке 19100 года» . Другие уже ответили на этот вопрос в достаточной степени (добавьте 1900 к результату getDate ()).

Может быть, книга, которую вы читаете о JavaScript, немного устарела?

Спасибо за взрыв из прошлого!

Джон
источник
Причина, по которой язык (Perl) не учел это, заключается в том, что он слепо копировал проектное решение C, которое было принято намного раньше. (20 лет?)
skiphoppy
Я бросал тень на JavaScript, а не на Perl. Perl часто предоставляет основные подпрограммы C. Как вы говорите, это продукт своего времени. JS, разработанный как минимум десятью годами позже, мог пойти другим путем.
jjohn
2

Вы должны, как указывалось, никогда не использовать getYear(), а вместо этого использовать getFullYear().

Однако история не так проста, как «IE реализует GetYear()как getFullYear(). Opera и IE в наши дни обрабатывают так, getYear()как getYear()было первоначально указано для дат до 2000 года, но будут рассматривать это как getFullYear()для дат после 2000 года, в то время как webkit и Firefox придерживаются старого поведения.

Это выводит 99 во всех браузерах:

javascript:alert(new Date(917823600000).getYear());

Это выводит 108 в FF / WebKit и 2008 в Opera / IE:

javascript:alert(new Date().getYear());
Arve
источник
1

Это глупо. Он датируется днями до 2000 года , а теперь просто возвращает количество лет, прошедших с 1900 года, по причинам наследия. Используйте getFullYear (), чтобы получить фактический год.

Joelhardi
источник
1

Я использую date.getUTCFullYear(); работает без проблем.

D3vito
источник
0

Вы получите число, прошедшее с 1900 года. Не спрашивайте меня, почему ..

Нильс Пипенбринк
источник
0

Как говорили другие, он возвращает количество лет, прошедших с 1900 года. Причина, по которой он это делает , заключается в том, что, когда в середине 90-х был изобретен JavaScript, такое поведение было одновременно удобным и согласованным с API-интерфейсами даты и времени на других языках. В частности C. И, конечно же, как только API был установлен, они не могли его изменить по причинам обратной совместимости.

user11318
источник
0

Кстати, разные браузеры могут возвращать разные результаты, поэтому лучше вообще пропустить эту функцию и всегда использовать getFullYear ().

Милан Бабушков
источник
0

var date_object = новая дата (); var year = date_object.getYear (); если (год <2000) {год = год + 1900; } // вы получите полный год ....


источник
-1

он возвращает четырехзначный год - 1900, что, возможно, было круто 9+ лет назад, но сейчас довольно отстает. Java java.util.Date также делает это.

user17163
источник