Почему java.util.Date представляет год как 1900 год?

In java.util.Date:

 * In all methods of class <code>Date</code> that accept or return
 * year, month, date, hours, minutes, and seconds values, the
 * following representations are used:
 * <ul>
 * <li>A year <i>y</i> is represented by the integer
 *     <i>y</i><code>-1900</code>.

Конечно, в Java 1.1 метод getYear() и ему подобные были объявлены устаревшими в пользу java.util.Calendar, у которого все еще есть это странное примечание об устаревании:

 int    getYear() 
    Deprecated. As of JDK version 1.1, replaced by Calendar.get(Calendar.YEAR) - 1900.

 setYear(int year) 
      Deprecated. As of JDK version 1.1, replaced by Calendar.set(Calendar.YEAR, year + 1900).

И, конечно же, Month основан на 0, но мы все это знаем (хотя можно подумать, что они убрали эту проблему из Calendar — это не так):

 * <li>A month is represented by an integer from 0 to 11; 0 is January,
 *     1 is February, and so forth; thus 11 is December.

Я проверил следующие вопросы:

Почему Java Date.getYear() возвращает 111 вместо 2011?

Почему API даты Java (java.util.Date, .Calendar) такой беспорядок?

Мой вопрос:

  • Что, возможно, могли получить первоначальные создатели java.util.Date от хранения данных «года», вычитая из него 1900? Особенно, если он в основном хранится как long.

Как таковой:

private transient long fastTime;

@Deprecated
public int getYear() {
    return normalize().getYear() - 1900;
} 

@Deprecated
public void setYear(int year) {
    getCalendarDate().setNormalizedYear(year + 1900);
}

private final BaseCalendar.Date getCalendarDate() {
    if (cdate == null) {
        BaseCalendar cal = getCalendarSystem(fastTime);
    ....
  • Почему 1900?

person EpicPandaForce    schedule 08.10.2014    source источник
comment
Вычисление с 1900 года — это длинный стандарт C из области Unix. И поскольку размеры слов были примерно 16 бит, они заняли круглый, но все же исторически недавний год. Конечно, благодаря Joda теперь в java 8 все поправлено в новых классах java.time, месяцах с 1 по 12 и так далее.   -  person Joop Eggen    schedule 08.10.2014
comment
До 2000 года расчет с 1900 года был удобен для отображения двухзначного года. Использование двузначных годов также оказало очень положительное влияние на рынок труда в области ИТ примерно в 1999 году.   -  person Erich Kitzmueller    schedule 08.10.2014
comment
java.util.Date была неудачной работой. (Именно поэтому в Java сейчас так много разных схем дат.) В частности, 1900 год традиционно был началом времени для компьютерных дат, поскольку до 2000 года год можно было представить в виде двух цифр на перфокарте (и ничего важного не происходило). до 1900 г.).   -  person Hot Licks    schedule 08.10.2014


Ответы (2)


По сути, оригинальные разработчики java.util.Date многое скопировали из C. То, что вы видите, является результатом этого — см. tm структура. Поэтому вы, вероятно, должны спросить, почему это было разработано для использования 1900 года. Я подозреваю, что основной ответ таков: «Потому что мы не очень хорошо разрабатывали API, когда был разработан tm». Я бы сказал, что мы по-прежнему не очень хороши в разработке API, когда речь идет о датах и ​​времени, потому что существует так много разных вариантов использования.

Это всего лишь API, а не формат хранения внутри java.util.Date. Не менее раздражает, заметьте.

person Jon Skeet    schedule 08.10.2014

java.util.Date вообще не дата. Это (цитируя http://docs.oracle.com/javase/6/docs/api/java/util/Date.html) определенный момент времени с точностью до миллисекунды.

Он не имеет отношения к какой-либо конкретной дате, часу и т. д. Вы можете извлечь из него день, год и т. д., используя заданный календарь и часовой пояс. Различные календари, часовые пояса дадут разные даты.

Если вы когда-нибудь захотите сохранить дату (день, месяц, год), не используйте java.util.Date

Вместо

person Bartosz Bilicki    schedule 08.10.2014
comment
Я думаю, что это не ответ на вопрос 1900 года. - person Meno Hochschild; 08.10.2014