Introducción al trabajo con fechas y horas en Java
Trabajar con fechas y horas es una de las tareas más comunes en el desarrollo. Ya sea para registro de eventos, cálculo de plazos, filtrado de datos o visualización de calendarios, no se puede prescindir de un manejo seguro de las API temporales. En Java, durante mucho tiempo se usaron las clases java.util.Date y java.util.Calendar, pero tenían numerosas desventajas: mutabilidad, API no intuitiva, problemas con hilos.
A partir de Java 8, se agregó al lenguaje un nuevo paquete java.time, basado en el estándar ISO-8601. Ofrece clases immutables (inmutables) y thread-safe que son mucho más cómodas de usar. En este artículo analizaremos tanto los enfoques antiguos como los nuevos, y mostraremos ejemplos prácticos de código.
1. Clases obsoletas: Date y Calendar
A pesar de que no se recomienda el uso de Date y Calendar en proyectos nuevos, puedes encontrarlos en código heredado. Veamos los puntos principales.
Clase java.util.Date
La clase Date representa un momento específico en el tiempo con precisión de milisegundos. Tiene muchos métodos obsoletos.
import java.util.Date;
public class DateExample { public static void main(String[] args) { // Fecha y hora actual Date now = new Date(); System.out.println("Hora actual: " + now);
// Constructor con milisegundos (desde el 1 de enero de 1970) Date specificDate = new Date(1000000000000L); System.out.println("Fecha: " + specificDate);
// Comparación de fechas boolean after = now.after(specificDate); System.out.println("¿now después de specificDate? " + after); }}Clase java.util.Calendar
Calendar es una clase más flexible, pero aún incómoda para la manipulación de fechas.
import java.util.Calendar;
public class CalendarExample { public static void main(String[] args) { Calendar cal = Calendar.getInstance(); // Establecer una fecha específica cal.set(2025, Calendar.MARCH, 15, 10, 30, 0); System.out.println("Fecha establecida: " + cal.getTime());
// Obtener campos individuales int year = cal.get(Calendar.YEAR); int month = cal.get(Calendar.MONTH) + 1; // Los meses empiezan en 0 int day = cal.get(Calendar.DAY_OF_MONTH); System.out.println("Año: " + year + ", Mes: " + month + ", Día: " + day);
// Añadir días cal.add(Calendar.DAY_OF_MONTH, 10); System.out.println("Dentro de 10 días: " + cal.getTime()); }}Desventajas: mutabilidad (los métodos modifican el propio objeto), complejidad al trabajar con zonas horarias, confusión con los índices de los meses.
2. API moderna: java.time (Java 8+)
El paquete java.time resuelve todos los problemas de las clases antiguas. Clases principales:
- LocalDate — fecha sin hora (año, mes, día);
- LocalTime — hora sin fecha (horas, minutos, segundos, nanosegundos);
- LocalDateTime — fecha y hora sin zona horaria;
- ZonedDateTime — fecha y hora con zona horaria;
- Instant — momento en el tiempo en UTC;
- Duration y Period — para trabajar con intervalos de tiempo.
LocalDate — trabajo con fechas
import java.time.LocalDate;import java.time.Month;
public class LocalDateExample { public static void main(String[] args) { // Fecha actual LocalDate today = LocalDate.now(); System.out.println("Hoy: " + today);
// Fecha específica LocalDate specific = LocalDate.of(2025, Month.DECEMBER, 25); System.out.println("Navidad: " + specific);
// Sumar días LocalDate nextWeek = to