El año es relativo a la época. Al establecer el año en algo menor o igual a 0, el calendario lo corrige automáticamente al cambiar la época (de AD a BC o de BC a AD). Este comportamiento es mejor conocido en los otros campos. P.ej. si establece el mes en algo negativo, el año se reduce en consecuencia.
Esas correcciones no se realizan de forma individual, sino que se realizan de una sola vez, generalmente cuando llama al getTime()
para leer la fecha resultante.
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
Así que en lugar de fijar el año 2001 a la que tendría que ponerlo en -2000 (porque el año 0 no existe en absoluto). O se podría configurar de forma explícita la época:
c2.set(Calendar.ERA, GregorianCalendar.AD);
Otra manera de resolver este "error" es por no la lectura del tiempo antes de la fecha completa se establece:
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
A la salida de la época de una fecha puede usar "G" en el patrón de SimpleDateFormat
:
new SimpleDateFormat("E MMM dd HH:mm:ss z yyyy G").format(c2.getTime())
// "Wed Jan 01 05:35:00 CET 2001 BC"
Miércoles vs lunes. Además, si configuro MILLISEC y SEC en 0 y comparo las dos fechas, no serán iguales. Originalmente mi propósito era normalizar la parte del día de los objetos DateTime para comparar solo la parte del tiempo. – differenziale
¡LOL! Que...? Sí, ese me pasó. Me parece que has identificado un error. – phatfingers
El comportamiento aberrante parece estar relacionado con el año c1 establecido en 0 (o años negativos, resulta). Cuando lo intento con años positivos, solo he visto el resultado correcto del lunes. – phatfingers