Ответ 1
Год относится к эпохе. Устанавливая год на что-то меньшее или равное 0, календарь автоматически корректирует это, переключая эру (от AD до BC или от BC до AD). Такое поведение лучше известно из других полей. Например. если вы установите месяц на что-то отрицательное, год будет уменьшаться соответствующим образом.
Эти исправления не производятся индивидуально, но они делаются все сразу, обычно, когда вы вызываете getTime()
для считывания итоговой даты.
Calendar c1 = Calendar.getInstance(); // August 16th, 2012 AD
c1.set(Calendar.YEAR, 0); // August 16th, 0 AD
c1.set(Calendar.DAY_OF_YEAR, 1); // January 1st, 0 AD
Date d1 = c1.getTime(); // January 1st, 1 BC (corrected)
Calendar c2 = Calendar.getInstance();
c2.setTime(d1);
c2.set(Calendar.YEAR, 2001); // January 1st, 2001 BC
c2.set(Calendar.DAY_OF_YEAR, 1);
System.out.println(c2.getTime()); // prints "Wed Jan 01 05:35:00 CET 2001"
// because 01/01/2001 BC was a Wednesday
Поэтому вместо того, чтобы устанавливать год к 2001 году, вам нужно установить его на -2000 (потому что год 0 вообще не существует). Или вы можете явно задать эру:
c2.set(Calendar.ERA, GregorianCalendar.AD);
Еще один способ решить эту "ошибку" - не, зачитывая время до установки полной даты:
Calendar c1 = Calendar.getInstance(); // August 16th, 2012 AD
c1.set(Calendar.YEAR, 0); // August 16th, 0 AD
c1.set(Calendar.DAY_OF_YEAR, 1); // January 1st, 0 AD
c1.set(Calendar.YEAR, 2001); // January 1st, 2001 AD
System.out.println(c1.getTime()); // prints the expected date
Чтобы вывести эру даты, вы можете использовать "G" в шаблоне SimpleDateFormat
:
new SimpleDateFormat("E MMM dd HH:mm:ss z yyyy G").format(c2.getTime())
// "Wed Jan 01 05:35:00 CET 2001 BC"