CodeGym /Cursos /JAVA 25 SELF /Resumen de la API java.time y diferencias respecto a las ...

Resumen de la API java.time y diferencias respecto a las API antiguas

JAVA 25 SELF
Nivel 13 , Lección 1
Disponible

1. Contexto histórico: cómo se trabajaba con fechas antes de Java 8

En la lejana antigüedad (antes de Java 8) para trabajar con fechas y horas se usaban las clases java.util.Date, java.util.Calendar y para el formateo — java.text.SimpleDateFormat. Era uno de esos casos en los que los programadores de todo el planeta suspiraban al unísono y, rechinando los dientes, escribían algo como:

import java.util.Date;

Date now = new Date();
System.out.println(now); // Mostrará algo extraño como "Wed Jun 05 14:15:22 MSK 2025"

Suena sencillo, pero en realidad no era tan bonito. He aquí solo algunas de las «alegrías» de la API antigua:

  • Date — objeto mutable. Podías cambiarlo accidentalmente y esto a menudo llevaba a bugs.
  • Los meses en Date y Calendar empezaban en cero (enero es 0, diciembre — 11), mientras que los días empezaban en uno.
  • SimpleDateFormat no era seguro para hilos: si dos hilos formateaban una fecha al mismo tiempo, podías obtener resultados inesperados.
  • Una enorme cantidad de métodos estaban marcados como @Deprecated (obsoletos), y el IDE te asustaba constantemente con advertencias amarillas.
  • Trabajar con zonas horarias era un auténtico dolor: era fácil confundir la hora local con UTC, y mejor ni hablar del cambio a horario de verano/invierno.

Ejemplo del dolor

import java.util.Date;

Date date = new Date(2025, 5, 1); // año 2025, mes 5 (¿junio?), día 1
System.out.println(date); // ¡No es lo que esperas!

2. Aparición de java.time: un nuevo enfoque

Para 2014 quedó claro: la API antigua no solo era incómoda — era peligrosa. Por eso en Java apareció el nuevo paquete — java.time, que implementa la especificación JSR‑310. Esta API se inspiró en la popular biblioteca Joda-Time y enseguida se convirtió en el estándar de facto.

Paquetes y clases principales

  • java.time — paquete principal donde viven todas las nuevas clases de fecha y hora.
  • java.time.format — para formatear y parsear fechas y horas.
  • java.time.temporal — para operaciones temporales más avanzadas.
  • java.time.zone — para trabajar con zonas horarias.

Estos son los protagonistas principales de la nueva API:

Clase ¿Para qué? Ejemplo de uso
LocalDate
Solo fecha (año, mes, día) Cumpleaños, sin hora
LocalTime
Solo hora (horas, minutos, segundos) Hora de una reunión, sin fecha
LocalDateTime
Fecha y hora, sin zona horaria Evento local
ZonedDateTime
Fecha y hora con zona horaria Reunión en Minsk en hora local
Instant
Instante absoluto (UTC) Marca de evento en el registro
Duration
Intervalo de tiempo (horas, minutos, seg.) Duración de una llamada
Period
Periodo (años, meses, días) Antigüedad laboral, edad

Ejemplo: crear una fecha a la manera nueva

import java.time.LocalDate;

LocalDate today = LocalDate.now();
System.out.println(today); // Por ejemplo, "2025-06-05"

3. Ventajas de la nueva API

Inmutabilidad (immutable)

Todas las clases de java.time son inmutables. Esto significa: si creas un objeto LocalDate, no puedes modificarlo. Cualquier operación (por ejemplo, añadir un día) devuelve un objeto nuevo.

LocalDate today = LocalDate.now();
LocalDate tomorrow = today.plusDays(1);

System.out.println(today);    // 2025-06-05
System.out.println(tomorrow); // 2025-06-06

Gestión explícita de las zonas horarias

En la API antigua era fácil olvidar en qué zona horaria estaba la fecha. En java.time todo es explícito: si necesitas zona horaria — usa ZonedDateTime, si no — usa LocalDateTime.

import java.time.ZonedDateTime;
import java.time.ZoneId;

ZonedDateTime MinskTime = ZonedDateTime.now(ZoneId.of("Europe/Minsk"));
System.out.println(MinskTime); // 2025-06-05T14:23:45+03:00[Europe/Minsk]

Métodos prácticos para cálculos y comparación

LocalDate today = LocalDate.now();
LocalDate nextMonth = today.plusMonths(1);
boolean isAfter = LocalDate.now().plusDays(1).isAfter(today); // true

Formateo y parseo

El formateo y el parseo se hacen con DateTimeFormatter (lo veremos en detalle en la próxima lección):

import java.time.format.DateTimeFormatter;

LocalDate today = LocalDate.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy");
String formatted = today.format(formatter); // "05.08.2025"

4. Compatibilidad: cómo convivir con el código antiguo

En el mundo real, muy a menudo hay que trabajar con bibliotecas o sistemas antiguos donde se usan Date y Calendar. Por suerte, la nueva API es amigable con el legado: se pueden convertir los tipos antiguos a los nuevos y viceversa.

Conversión DateInstant

import java.util.Date;
import java.time.Instant;

// Date → Instant
Date legacyDate = new Date();
Instant instant = legacyDate.toInstant();

// Instant → Date
Date dateBack = Date.from(instant);

Conversión CalendarZonedDateTime

import java.util.Calendar;
import java.time.ZonedDateTime;
import java.time.ZoneId;
import java.util.Date;

// Calendar → ZonedDateTime
Calendar calendar = Calendar.getInstance();
ZonedDateTime zdt = ZonedDateTime.ofInstant(
        calendar.toInstant(),
        calendar.getTimeZone().toZoneId()
);

// ZonedDateTime → Calendar
Calendar calBack = Calendar.getInstance();
calBack.setTime(Date.from(zdt.toInstant()));

Tabla: correspondencia entre clases antiguas y nuevas

Clase antigua Clase nueva Comentario
java.util.Date
Instant
Tiempo absoluto
java.util.Calendar
ZonedDateTime
Fecha y hora con zona horaria
java.text.SimpleDateFormat
DateTimeFormatter
Formateo/parseo de fechas

5. Práctica: primeros pasos con java.time

Supongamos que tienes un usuario con fecha de nacimiento. La guardaremos y la mostraremos:

import java.time.LocalDate;

public class UserProfile {
    private String name;
    private LocalDate birthDate;

    public UserProfile(String name, LocalDate birthDate) {
        this.name = name;
        this.birthDate = birthDate;
    }

    public void printProfile() {
        System.out.println("Nombre: " + name);
        System.out.println("Fecha de nacimiento: " + birthDate);
    }
}

public class Main {
    public static void main(String[] args) {
        UserProfile user = new UserProfile("Alisa", LocalDate.of(1998, 12, 25));
        user.printProfile();
    }
}

Salida:

Nombre: Alisa
Fecha de nacimiento: 1998-12-25

6. Comparación: API antigua vs API nueva

Ejemplo: añadir una semana a la fecha de nacimiento

Forma antigua (Date/Calendar):

import java.util.Calendar;

Calendar cal = Calendar.getInstance();
cal.set(1998, Calendar.DECEMBER, 25);
cal.add(Calendar.WEEK_OF_YEAR, 1);
System.out.println(cal.getTime()); // Engorroso y poco evidente

Forma nueva (java.time):

import java.time.LocalDate;

LocalDate birthDate = LocalDate.of(1998, 12, 25);
LocalDate nextWeek = birthDate.plusWeeks(1);
System.out.println(nextWeek); // 1999-01-01

Con la nueva API el código es más corto, más simple y más seguro.

7. Errores típicos al trabajar con java.time

Error n.º 1: olvidar que los objetos son inmutables.
Si llamas a date.plusDays(1); y no guardas el resultado, la fecha original se queda igual.

Error n.º 2: confundir LocalDate con LocalDateTime.
LocalDate almacena solo la fecha (año, mes, día), mientras que LocalDateTime también la hora. No los confundas si necesitas procesar horas y minutos.

Error n.º 3: usar clases antiguas en proyectos nuevos.
Si puedes — usa siempre java.time. Las clases antiguas solo para compatibilidad.

Error n.º 4: manejar mal las zonas horarias.
Si necesitas almacenar un evento importante para distintas regiones, utiliza ZonedDateTime o al menos Instant. ¡LocalDateTime no contiene información de zona horaria!

Error n.º 5: intentar comparar directamente LocalDate y LocalDateTime.
Son tipos de datos distintos; no se pueden comparar directamente. Primero conviértelos a un mismo tipo.

1
Tarea
JAVA 25 SELF, nivel 13, lección 1
Bloqueada
Marcar el día actual en el calendario 🗓️
Marcar el día actual en el calendario 🗓️
1
Tarea
JAVA 25 SELF, nivel 13, lección 1
Bloqueada
Una mirada atrás: ¿qué día fue ayer? ⏪
Una mirada atrás: ¿qué día fue ayer? ⏪
1
Tarea
JAVA 25 SELF, nivel 13, lección 1
Bloqueada
Mirando al futuro: ¿qué día será mañana? ⏩
Mirando al futuro: ¿qué día será mañana? ⏩
1
Tarea
JAVA 25 SELF, nivel 13, lección 1
Bloqueada
Registro de un momento histórico importante 📜
Registro de un momento histórico importante 📜
Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION