Clase Calendar de Java
La clase Calendar es una clase abstracta en Java para manejar fechas y horas, que se encuentra en eljava.utilpaquete. Esta clase proporciona una serie de métodos para operar con campos de fecha y hora (como año, mes, día, hora, minuto, etc.), y puede realizar cálculos y comparaciones de fechas.
¿Por qué se necesita la clase Calendar?
En Java, aunque la clase Date también puede representar fechas y horas, tiene las siguientes limitaciones:
- La mayoría de sus métodos están obsoletos (deprecated)
- No admite internacionalización
- Funcionalidad limitada para el cálculo de fechas
La clase Calendar resuelve estos problemas y proporciona funciones de operación de fecha y hora más potentes y flexibles.
Uso básico de la clase Calendar
Obtener una instancia de Calendar
Debido a que Calendar es una clase abstracta, no podemos instanciarla directamente. El método estándar para obtener una instancia de Calendar es:
Ejemplo
Este método devuelve una instancia de Calendar (normalmente GregorianCalendar) según la zona horaria y la región predeterminadas.
Establecer fecha y hora
Podemos utilizar elset()método para establecer los distintos campos del objeto Calendar:
Ejemplo
calendar.set(2023, Calendar.NOVEMBER, 15);
// Establecer año, mes, día, hora, minuto y segundo
calendar.set(2023, Calendar.NOVEMBER, 15, 14, 30, 0);
Nota: los meses comienzan desde 0; 0 representa enero y 11 representa diciembre. Para evitar confusiones, se recomienda usar las constantes definidas en la clase Calendar (como Calendar.JANUARY, Calendar.FEBRUARY, etc.).
Obtener información de fecha y hora
Usando elget()método se pueden obtener los distintos campos del objeto Calendar:
Ejemplo
int month = calendar.get(Calendar.MONTH); // Obtener el mes (0-11)
int day = calendar.get(Calendar.DAY_OF_MONTH);// Obtener el día
int hour = calendar.get(Calendar.HOUR_OF_DAY);// Obtener la hora (formato de 24 horas)
int minute = calendar.get(Calendar.MINUTE); // Obtener los minutos
int second = calendar.get(Calendar.SECOND); // Obtener los segundos
Métodos comunes de la clase Calendar
Cálculo de fechas
La clase Calendar proporciona métodos convenientes para el cálculo de fechas:
Ejemplo
calendar.add(Calendar.DAY_OF_MONTH, 10);
// Restar 3 meses al mes actual
calendar.add(Calendar.MONTH, -3);
Comparación de fechas
Podemos utilizar elcompareTo()método para comparar dos objetos Calendar:
Ejemplo
Calendar cal2 = Calendar.getInstance();
cal2.add(Calendar.DAY_OF_MONTH, 1);
int result = cal1.compareTo(cal2);
// result < 0 indica que cal1 es anterior a cal2
// result == 0 indica que cal1 es igual a cal2
// result > 0 indica que cal1 es posterior a cal2
Obtener la marca de tiempo (timestamp)
Se puede utilizar elgetTimeInMillis()método para obtener la marca de tiempo (en milisegundos) representada por el objeto Calendar:
Ejemplo
También se puede utilizar elgetTime()método para convertirlo en un objeto Date:
Ejemplo
Usos avanzados de la clase Calendar
Establecer zona horaria
Podemos establecer una zona horaria específica para el objeto Calendar:
Ejemplo
calendar.setTimeZone(timeZone);
Operaciones con campos del calendario
La clase Calendar proporciona elroll()método, que permite desplazar un campo sin afectar a otros campos:
Ejemplo
calendar.roll(Calendar.MONTH, true); // o calendar.roll(Calendar.MONTH, 1);
Obtener el primer día de la semana
La definición del primer día de la semana varía según la región (en algunos lugares es domingo, en otros es lunes):
Ejemplo
Ejemplo completo
Ejemplo
import java.util.GregorianCalendar;
import java.text.SimpleDateFormat;
public class CalendarDemo {
public static void main(String[] args) {
// 1. Obtener una instancia de Calendar (por defecto usa la fecha y hora actuales)
Calendar calendar = Calendar.getInstance();
// 2. Obtener los valores de cada campo
int year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH) + 1; // El mes comienza desde 0, hay que sumar 1
int day = calendar.get(Calendar.DAY_OF_MONTH);
int hour = calendar.get(Calendar.HOUR_OF_DAY); // Formato de 24 horas
int minute = calendar.get(Calendar.MINUTE);
int second = calendar.get(Calendar.SECOND);
System.out.printf("Hora actual: %d año %d mes %d día %d:%d:%d%n",
year, month, day, hour, minute, second);
// 3. Establecer una fecha y hora específicas
calendar.set(2023, Calendar.MAY, 15, 10, 30, 0); // 15 de mayo de 2023, 10:30:00
// 4. Usar SimpleDateFormat para formatear la salida
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("Hora establecida: " + sdf.format(calendar.getTime()));
// 5. Operaciones con fechas
calendar.add(Calendar.DAY_OF_MONTH, 5); // Añadir 5 días
calendar.add(Calendar.HOUR, -3); // Restar 3 horas
System.out.println("Hora después de la operación: " + sdf.format(calendar.getTime()));
// 6. Comparar fechas
Calendar anotherCalendar = new GregorianCalendar(2023, Calendar.JUNE, 1);
System.out.println("Resultado de la comparación: " +
(calendar.before(anotherCalendar) ? "antes" : "después"));
// 7. Obtener el día de la semana (domingo=1, sábado=7)
int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
System.out.println("Día de la semana " + getChineseWeekday(dayOfWeek));
}
private static String getChineseWeekday(int dayOfWeek) {
String[] weekdays = {"", "domingo", "lunes", "martes", "miércoles", "jueves", "viernes", "sábado"};
return weekdays[dayOfWeek];
}
}
Resultado de salida:
当前时间: 2023年5月15日 14:25:36 设置后的时间: 2023-05-15 10:30:00 运算后的时间: 2023-05-20 07:30:00 比较结果: 之前 星期二
Consideraciones sobre la clase Calendar
El mes comienza desde 0: En la clase Calendar, los meses comienzan desde 0 (0=enero, 11=diciembre), lo que puede dar lugar a errores.
Mutabilidad: Los objetos Calendar son mutables; modificar un objeto Calendar afecta a todos los lugares que lo referencian.
Seguridad para hilos (thread safety): La clase Calendar no es segura para hilos; en entornos multihilo se necesita sincronización adicional.
Rendimiento: Crear instancias de Calendar con frecuencia afecta al rendimiento; se puede considerar reutilizar instancias.
Problemas de zona horaria: Por defecto se usa la zona horaria del sistema; en aplicaciones que cruzan zonas horarias se debe prestar especial atención.
Alternativas en Java 8
Desde Java 8, se introdujo la nueva API de fecha y hora (java.timepaquete), que proporciona una forma más moderna y fácil de manejar fechas y horas. Si se usa Java 8 o una versión superior, se recomienda usar la nueva API:
Ejemplo
LocalDate date = LocalDate.now();
LocalDateTime dateTime = LocalDateTime.now();
ZonedDateTime zonedDateTime = ZonedDateTime.now();
La nueva API resuelve muchos problemas de la clase Calendar, incluyendo una mejor seguridad para hilos, un diseño de API más intuitivo y funciones más potentes.
Métodos comunes de la clase Calendar de Java
A continuación se presentan los métodos comunes de la clase java.util.Calendar:
Métodos básicos
| Método | Descripción | Ejemplo |
|---|---|---|
static Calendar getInstance() |
Obtener una instancia de Calendar con la zona horaria y la configuración regional predeterminadas | Calendar cal = Calendar.getInstance() |
static Calendar getInstance(TimeZone zone) |
Obtener una instancia de Calendar con una zona horaria específica | Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT+8")) |
static Calendar getInstance(Locale locale) |
Obtener una instancia de Calendar con una configuración regional específica | Calendar cal = Calendar.getInstance(Locale.CHINA) |
static Calendar getInstance(TimeZone zone, Locale locale) |
Obtener una instancia de Calendar con una zona horaria y configuración regional específicas | Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT+8"), Locale.CHINA) |
Constantes de campo (comunes)
| Campo | Descripción | Rango de valores |
|---|---|---|
Calendar.YEAR |
Campo del año | - |
Calendar.MONTH |
Campo del mes | 0-11 (0 representa enero) |
Calendar.DATEoCalendar.DAY_OF_MONTH |
Día del mes | 1-31 |
Calendar.DAY_OF_WEEK |
Día de la semana | 1-7 (1 representa domingo) |
Calendar.HOUR |
Hora en formato de 12 horas | 0-11 |
Calendar.HOUR_OF_DAY |
Hora en formato de 24 horas | 0-23 |
Calendar.MINUTE |
Minutos | 0-59 |
Calendar.SECOND |
segundo | 0-59 |
Calendar.MILLISECOND |
Milisegundos | 0-999 |
Calendar.AM_PM |
AM o PM (mañana o tarde) | 0 (AM) o 1 (PM) |
Métodos de operación de fecha y hora
| Método | Descripción | Ejemplo |
|---|---|---|
int get(int field) |
Obtener el valor del campo especificado | int year = cal.get(Calendar.YEAR) |
void set(int field, int value) |
Establecer el valor del campo especificado | cal.set(Calendar.MONTH, 5)(Establecer a junio) |
void set(int year, int month, int date) |
Establecer año, mes, día | cal.set(2023, 5, 15)(15 de junio de 2023) |
void set(int year, int month, int date, int hourOfDay, int minute) |
Establecer año, mes, día, hora, minuto | cal.set(2023, 5, 15, 14, 30) |
void set(int year, int month, int date, int hourOfDay, int minute, int second) |
Establecer año, mes, día, hora, minuto, segundo | cal.set(2023, 5, 15, 14, 30, 45) |
void add(int field, int amount) |
Añadir o restar la cantidad de tiempo especificada | cal.add(Calendar.DATE, 5)(Añadir 5 días) |
void roll(int field, int amount) |
Añadir o restar una cantidad de tiempo sin cambiar campos mayores | cal.roll(Calendar.DATE, 5)(Solo cambia el campo de día) |
Métodos de comparación de tiempo
| Método | Descripción | Ejemplo |
|---|---|---|
boolean after(Object when) |
Determina si este Calendar está después del tiempo especificado | cal1.after(cal2) |
boolean before(Object when) |
Determina si este Calendar está antes del tiempo especificado | cal1.before(cal2) |
int compareTo(Calendar anotherCalendar) |
Compara el orden temporal de dos objetos Calendar | cal1.compareTo(cal2) |
Otros métodos útiles
| Método | Descripción | Ejemplo |
|---|---|---|
long getTimeInMillis() |
Devuelve el valor de tiempo de este Calendar (milisegundos) | long millis = cal.getTimeInMillis() |
void setTimeInMillis(long millis) |
Establece el Calendar con el valor de tiempo en milisegundos dado | cal.setTimeInMillis(1626345600000L) |
Date getTime() |
Devuelve un objeto Date que representa el valor de tiempo de este Calendar | Date date = cal.getTime() |
void setTime(Date date) |
Establece el tiempo del Calendar usando el Date dado | cal.setTime(new Date()) |
void clear() |
Borrar todos los valores de campo | cal.clear() |
void clear(int field) |
Borrar el valor del campo especificado | cal.clear(Calendar.HOUR) |
boolean isSet(int field) |
Determina si el campo especificado tiene un valor establecido | if(cal.isSet(Calendar.YEAR)) |