1. Cambiar de Dateclase a Calendarclase

A los programadores les encantó la Dateclase por su simplicidad y compatibilidad con los estándares de Unix, pero como saben, cada rosa tiene sus espinas.

Los programadores querían una Dateclase "inteligente". Y consiguieron lo que querían en la forma de la Calendarclase. Fue concebido como una forma no solo de almacenar fechas, sino también de realizar operaciones difíciles con fechas.

El nombre completo de la Calendarclase es java.util.Calendar. No olvide agregarlo a una declaración de importación si decide usarlo en su código.

Puede crear un Calendarobjeto con este comando:

Calendar date = Calendar.getInstance();

getInstance()El método estático de la Calendarclase crea un Calendarobjeto inicializado con la fecha actual. El calendario que desea se creará en función de la configuración de la computadora que ejecuta el programa.

O más exactamente, el calendario que obtienes... Eso es porque los humanos en la Tierra no están limitados a un solo calendario. En cambio, usan muchos. Y casi todos ellos están asociados a alguna religión o país. La Calendarclase admite 3 de ellos:

Calendario Descripción
Calendario Gregoriano calendario gregoriano cristiano
BudistaCalendario calendario budista
JaponésImperialCalendario calendario imperial japonés

Pero también hay calendarios chino y árabe. Básicamente, trabajar con el tiempo no es tan fácil como parece.

En el calendario chino, el año es oficialmente 4716 al momento de escribir esta lección. Y según el calendario musulmán, el año es 1398. Bienvenido al gran mundo, mi amigo programador.

2. Crear un objeto de calendario

Usaremos el calendario gregoriano, ya que es el más común en el mundo. Al menos hasta que China compre Oracle y haga del calendario chino el principal.

Puede crear un objeto de calendario con cualquier fecha usando una declaración como esta:

Calendar date = new GregorianCalendar(year, month, day);

Sí, tienes que escribir GregorianCalendarcada vez. En lugar de Calendar, también puedes escribir GregorianCalendar, eso también funcionará. Pero escribir solo Calendares más corto.

El año debe escribirse completo, por ejemplo, no puede escribir 19 en lugar de 2019. Los meses todavía se numeran desde cero. Pero como antes, los días del mes no se numeran desde cero. ¡Nerds!

Para establecer la hora y la fecha, debe pasar la hora como argumentos adicionales:

... = new GregorianCalendar(year, month, day, hours, minutes, seconds);

Incluso puede pasar en milisegundos si es necesario. Son el parámetro después del número de segundos.

3. Mostrar un objeto de calendario en la pantalla

Si simplemente imprime un objeto de calendario en la pantalla, no estará muy satisfecho con el resultado.

Código
Calendar calendar = new GregorianCalendar(2019, 03, 12);
System.out.println(calendar);
Salida de consola
java.util.GregorianCalendar[time=?,areFieldsSet=false,areAllFieldsSet=false,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Europe/Helsinki",offset=7200000,dstSavings=3600000,useDaylight=true,transitions=118,lastRule=java.util.SimpleTimeZone[id=Europe/Helsinki,offset=7200000,dstSavings=3600000,useDaylight=true,startYear=0,startMode=2,startMonth=2,startDay=-1,startDayOfWeek=1,startTime=3600000,startTimeMode=2,endMode=2,endMonth=9,endDay=-1,endDayOfWeek=1,endTime=3600000,endTimeMode=2]],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=?,YEAR=2019,MONTH=3,WEEK_OF_YEAR=?,WEEK_OF_MONTH=?,DAY_OF_MONTH=12,DAY_OF_YEAR=?,DAY_OF_WEEK=?,DAY_OF_WEEK_IN_MONTH=?,AM_PM=0,HOUR=0,HOUR_OF_DAY=0,MINUTE=0,SECOND=0,MILLISECOND=?,ZONE_OFFSET=?,DST_OFFSET=?]

Lo que hay que tener en cuenta aquí es que un calendario es un calendario, no una fecha : tiene todo tipo de configuraciones que se mostrarán en la pantalla.

Sería apropiado usar un SimpleDateFormatobjeto para mostrar un calendario, pero hasta que lo estudiemos, puedes usar este truco.

Date date = calendar.getTime();

Un Calendarobjeto se puede convertir fácilmente en un Dateobjeto y ya sabe cómo mostrar un Dateobjeto. Puede usar un código como este para convertir un Calendarobjeto en un Date:

Usando el getTime()método:

Código Salida de consola
Calendar calendar = new GregorianCalendar(2019, 03, 12);
System.out.println(calendar.getTime());
 Fri Apr 12 00:00:00 EEST 2019

Ese es un asunto bastante diferente, ¿no?

4. Trabajar con elementos de una fecha

Para obtener un elemento específico de una fecha (por ejemplo, el año, mes, ...), la Calendarclase tiene el get()método. Es un método único, pero tiene parámetros:

int month = calendar.get(Calendar.MONTH);

Donde calendares una Calendarvariable, y MONTHes un campo constante de la Calendarclase.

Pasa uno de los Calendarcampos constantes de la clase como argumento al getmétodo y obtiene el valor deseado como resultado.

Ejemplos

Código Descripción
Calendar calendar = Calendar.getInstance();

int era = calendar.get(Calendar.ERA);
int year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH);
int day = calendar.get(Calendar.DAY_OF_MONTH);

int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
int hour = calendar.get(Calendar.HOUR);
int minute = calendar.get(Calendar.MINUTE);
int second = calendar.get(Calendar.SECOND);


era (antes o después de la era común)
año
mes
día del mes

día de la semana
horas
minutos
segundos

Para cambiar un elemento de una fecha, utilice el setmétodo:

calendar.set(Calendar.MONTH, value);

Donde calendares una Calendarvariable, y MONTHes un campo constante de la Calendarclase.

Cuando trabaja con setel método, pasa uno de los Calendarcampos constantes de la clase como primer argumento y el nuevo valor como segundo argumento.

Ejemplos

Código Descripción
Calendar calendar = new GregorianCalendar();

calendar.set(Calendar.YEAR, 2019);
calendar.set(Calendar.MONTH, 6);
calendar.set(Calendar.DAY_OF_MONTH, 4);
calendar.set(Calendar.HOUR_OF_DAY, 12);
calendar.set(Calendar.MINUTE, 15);
calendar.set(Calendar.SECOND, 0);

System.out.println(calendar.getTime());


año = 2019
mes = julio (numerado desde 0)
4º día
horas
minutos
segundos

5. Constantes de la Calendarclase

Los campos constantes de la Calendarclase no se limitan a aquellos para nombrar elementos de una fecha. Parece que hay campos para cada ocasión.

Calendar date = new GregorianCalendar(2019, Calendar.JANUARY, 31);

Por ejemplo, hay campos constantes para referirse a meses:

Y también los días de la semana:

Calendar calendar = new GregorianCalendar(2019, Calendar.JANUARY, 31);
if (calendar.get(Calendar.DAY_OF_WEEK) == Calendar.FRIDAY)
{
   System.out.println("It's Friday");
}

No enumeraremos todo. Simplemente no queremos que se sorprenda si ve constantes como esta en el código.

El uso de constantes hace que el código sea más legible, razón por la cual los programadores las usan. Y los meses están numerados desde cero también para mejorar la legibilidad. O no.

6. Cambiar la fecha en un Calendarobjeto

La Calendarclase tiene un método que le permite operar en una fecha de manera más inteligente. Por ejemplo, puede agregar un año, un mes o varios días a una fecha. O llévatelos. Este método se llama add(). Trabajar con él se ve así:

calendar.add(Calendar.MONTH, value);

Donde calendares una Calendarvariable, y MONTHes un campo constante de la Calendarclase.

Cuando trabaja con addel método, pasa uno de los Calendarcampos constantes de la clase como primer argumento y como segundo argumento: el nuevo valor que se agregará.

Este es otro método inteligente. Veamos qué tan inteligente es:

Código
Calendar calendar = new GregorianCalendar(2019, Calendar.FEBRUARY, 27);
calendar.add(Calendar.DAY_OF_MONTH, 2);
System.out.println(calendar.getTime());
Salida de consola
Fri Mar 01 00:00:00 EET 2019

Este método entiende que solo hay 28 días en febrero de 2019, por lo que la fecha resultante es el 1 de marzo.

Ahora vamos a quitar 2 meses! ¿Qué debemos obtener? 27 de diciembre de 2018! Comprobemos ahora.

Para realizar una operación que da como resultado una fecha anterior, debe pasar un valor negativo al add()método:

Código
Calendar calendar = new GregorianCalendar(2019, Calendar.FEBRUARY, 27);
calendar.add(Calendar.MONTH, -2);
System.out.println(calendar.getTime());
Salida de consola
Thu Dec 27 00:00:00 EET 2018

¡Funciona!

Este método tiene en cuenta las diferentes duraciones de los meses, así como los años bisiestos. En definitiva, un gran método. Es exactamente lo que necesitan la mayoría de los programadores que trabajan con fechas.

7. Elementos rodantes de una fecha

Pero a veces hay situaciones en las que no queremos este comportamiento inteligente, por ejemplo, quieres hacer algo en una parte de la fecha sin cambiar todo lo demás.

La Calendarclase tiene el roll()método especial para esto. Su firma es como el add()método, pero este método cambia solo un elemento de la fecha, dejando el resto sin cambios.

Ejemplo:

Código
Calendar calendar = new GregorianCalendar(2019, Calendar.FEBRUARY, 27);
calendar.roll(Calendar.MONTH, -2);
System.out.println(calendar.getTime());
Salida de consola
Fri Dec 27 00:00:00 EET 2019

Cambiamos el mes, pero el año y la fecha permanecieron sin cambios.