CodeGym /Cursos /JAVA 25 SELF /Cálculos y comparación de fechas, Duration, Period

Cálculos y comparación de fechas, Duration, Period

JAVA 25 SELF
Nivel 13 , Lección 5
Disponible

1. Suma y resta de fechas y horas

En programación, trabajar con fechas y horas no es solo «mostrar la fecha bonita en pantalla». Muy a menudo se necesita:

  • saber cuántos días quedan hasta un evento importante;
  • calcular la edad de un usuario;
  • determinar cuánto tiempo ha pasado entre dos eventos;
  • comprobar si ya ha llegado la fecha límite;
  • sumar a una fecha una cantidad determinada de días, semanas, meses u horas.

Por ejemplo, en nuestra aplicación queremos recordar al usuario que quedan 3 días hasta la fecha límite de una tarea. O felicitarle por su cumpleaños pasado (si la fecha ya quedó en el pasado).

Para ello, en java.time hay clases y métodos especiales que hacen estos cálculos de forma sencilla y segura.

Métodos principales para sumar y restar

Todas las clases de fecha y hora (LocalDate, LocalTime, LocalDateTime, ZonedDateTime, Instant) tienen métodos:

  • plusXxx() — sumar (días, meses, años, horas, minutos, etc.)
  • minusXxx() — restar (lo mismo)
import java.time.LocalDate;

LocalDate today = LocalDate.now(); // Fecha de hoy
LocalDate tomorrow = today.plusDays(1); // Mañana
LocalDate nextMonth = today.plusMonths(1); // Dentro de un mes
LocalDate lastWeek = today.minusWeeks(1); // Hace una semana

System.out.println("Hoy: " + today);
System.out.println("Mañana: " + tomorrow);
System.out.println("Dentro de un mes: " + nextMonth);
System.out.println("Hace una semana: " + lastWeek);

Todos estos métodos devuelven un nuevo objeto y no modifican el original. ¡La inmutabilidad lo es todo!

import java.time.LocalTime;

LocalTime now = LocalTime.now();
LocalTime inTwoHours = now.plusHours(2);
LocalTime tenMinutesAgo = now.minusMinutes(10);

System.out.println("Ahora: " + now);
System.out.println("Dentro de 2 horas: " + inTwoHours);
System.out.println("Hace 10 minutos: " + tenMinutesAgo);

Métodos combinados

LocalDate vacation = today.plusMonths(2).plusDays(10);
System.out.println("Vacaciones: " + vacation);

2. Obtener la diferencia entre fechas: Period y Duration

Cuando hay que saber cuánto tiempo pasó entre dos fechas o momentos, entran en escena dos protagonistas — Period y Duration. Conozcámoslos más de cerca.

¿Cuál es la diferencia entre Period y Duration?

  • Period — para trabajar con fechas (año, mes, día). Por ejemplo, «3 años, 2 meses y 5 días».
  • Duration — para trabajar con tiempo (horas, minutos, segundos, nanosegundos). Por ejemplo, «5 horas 30 minutos».
Clase Para qué sirve Ejemplo de uso
Period
Diferencia entre fechas Cuántos años/meses/días hay entre fechas
Duration
Diferencia entre instantes Cuántas horas/minutos/segundos hay entre eventos

Ejemplo: calcular la edad de un usuario

import java.time.LocalDate;
import java.time.Period;

LocalDate birthday = LocalDate.of(2000, 1, 15); // Fecha de nacimiento
LocalDate today = LocalDate.now();

Period age = Period.between(birthday, today);

System.out.println("Edad: " + age.getYears() + " años, " +
                   age.getMonths() + " meses, " +
                   age.getDays() + " días");

Analogía: Period es como la diferencia «humana» entre fechas («tengo 24 años 5 meses 12 días»).

Ejemplo: cuánto tiempo queda hasta la fecha límite

import java.time.LocalDate;

LocalDate deadline = LocalDate.of(2025, 7, 1);
LocalDate today = LocalDate.now();

if (today.isBefore(deadline)) {
    Period left = Period.between(today, deadline);
    System.out.println("Hasta la fecha límite queda: " +
        left.getMonths() + " meses y " +
        left.getDays() + " días");
} else {
    System.out.println("¡La fecha límite ya ha pasado!");
}

Duration: diferencia en el tiempo

import java.time.LocalDateTime;
import java.time.Duration;

LocalDateTime start = LocalDateTime.of(2025, 6, 1, 10, 0, 0);
LocalDateTime end = LocalDateTime.of(2025, 6, 1, 15, 30, 0);

Duration duration = Duration.between(start, end);

System.out.println("Duración: " + duration.toHours() + " horas " +
                   (duration.toMinutes() % 60) + " minutos");

Duration mide la diferencia en segundos, minutos, horas, días (pero los días son siempre de 24 horas, sin tener en cuenta particularidades del calendario).

Comparación: ¿cuándo usar Period y cuándo Duration?

  • Si solo tienes fechas (sin hora), usa Period.
  • Si hay hora (por ejemplo, LocalDateTime, Instant), usa Duration.

3. Comparación de fechas y horas: isBefore, isAfter, equals

A veces solo necesitas entender: ¿la fecha ya ha llegado o aún no? ¿El evento está en el pasado o en el futuro? Para ello, todas las clases de fecha y hora tienen métodos:

  • isBefore(otraFecha)
  • isAfter(otraFecha)
  • isEqual(otraFecha) (o simplemente equals)
import java.time.LocalDate;

LocalDate today = LocalDate.now();
LocalDate deadline = LocalDate.of(2025, 7, 1);

if (today.isBefore(deadline)) {
    System.out.println("¡Aún hay tiempo!");
} else if (today.isEqual(deadline)) {
    System.out.println("¡Hoy es la fecha límite!");
} else {
    System.out.println("La fecha límite ya ha pasado :(");
}
import java.time.LocalTime;

LocalTime now = LocalTime.now();
LocalTime lunch = LocalTime.of(13, 0);

if (now.isAfter(lunch)) {
    System.out.println("¡La comida ya ha pasado!");
} else {
    System.out.println("Todavía queda tiempo hasta la comida.");
}

Importante: solo se pueden comparar objetos del mismo tipo (LocalDate con LocalDate, LocalDateTime con LocalDateTime, etc.).

4. Práctica: ejercicios de cálculo de diferencias y comprobación de plazos

Ejemplo: cuántos días quedan hasta la fecha límite de una tarea

import java.time.LocalDate;
import java.time.temporal.ChronoUnit;

LocalDate today = LocalDate.now();
LocalDate deadline = LocalDate.of(2025, 7, 1);

long daysLeft = ChronoUnit.DAYS.between(today, deadline);

if (daysLeft > 0) {
    System.out.println("Hasta la fecha límite quedan " + daysLeft + " días");
} else if (daysLeft == 0) {
    System.out.println("¡Hoy es la fecha límite!");
} else {
    System.out.println("La fecha límite fue hace " + Math.abs(daysLeft) + " días");
}

ChronoUnit.DAYS.between() es una forma práctica de saber la cantidad exacta de días entre dos fechas (sin tener en cuenta meses y años).

Ejemplo: cuántos segundos hay entre dos eventos

import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;

LocalDateTime start = LocalDateTime.of(2025, 6, 1, 10, 0, 0);
LocalDateTime end = LocalDateTime.of(2025, 6, 1, 15, 30, 0);

long seconds = ChronoUnit.SECONDS.between(start, end);

System.out.println("Entre los eventos han pasado " + seconds + " segundos");

Ejemplo: calcular la antigüedad de una tarea

import java.time.LocalDate;
import java.time.Period;

LocalDate created = LocalDate.of(2025, 5, 20);
LocalDate today = LocalDate.now();

Period period = Period.between(created, today);

System.out.println("La tarea se creó hace " +
    period.getDays() + " días, " +
    period.getMonths() + " meses y " +
    period.getYears() + " años.");

Ejemplo: duración entre dos Instant

import java.time.Instant;
import java.time.Duration;

Instant start = Instant.now();
// ... hacemos algo ...
Instant end = Instant.now();

Duration duration = Duration.between(start, end);

System.out.println("La ejecución tardó " + duration.toMillis() + " milisegundos");

5. Particularidades del uso de Period y Duration

Particularidades de Period

  • Period calcula la diferencia según el calendario: entre el 28 de febrero y el 1 de marzo — 1 día, aunque sean meses distintos.
  • Se puede obtener la cantidad de años, meses y días por separado: getYears(), getMonths(), getDays().
  • Si necesitas saber la cantidad total de días entre fechas, usa ChronoUnit.DAYS.between().

Particularidades de Duration

  • Duration trabaja con tiempo exacto (horas, minutos, segundos).
  • Puede trabajar con LocalTime, LocalDateTime, Instant.
  • No se puede usar para fechas sin hora (LocalDate): lanzará una excepción.

Ejemplo: diferencia entre Period y Duration

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.Duration;
import java.time.Period;

LocalDate date1 = LocalDate.of(2025, 2, 28);
LocalDate date2 = LocalDate.of(2025, 3, 1);

Period period = Period.between(date1, date2); // 2 días (año bisiesto)
long days = java.time.temporal.ChronoUnit.DAYS.between(date1, date2); // 2 días

System.out.println("Period: " + period.getDays() + " días");
System.out.println("ChronoUnit: " + days + " días");

LocalDateTime dt1 = LocalDateTime.of(2025, 6, 1, 23, 0);
LocalDateTime dt2 = LocalDateTime.of(2025, 6, 2, 1, 0);

Duration duration = Duration.between(dt1, dt2); // 2 horas
System.out.println("Duration: " + duration.toHours() + " horas");

6. Uso de Duration y Period para mostrar la diferencia en un formato cómodo

Cuando calculas la diferencia entre fechas u horas para el usuario, no siempre es útil mostrar «123456 segundos». Normalmente se quiere algo como «2 días 3 horas 15 minutos».

Ejemplo: mostrar la diferencia entre fechas y horas

import java.time.LocalDateTime;
import java.time.Duration;

LocalDateTime start = LocalDateTime.of(2025, 6, 1, 14, 0);
LocalDateTime end = LocalDateTime.of(2025, 6, 3, 16, 30);

Duration duration = Duration.between(start, end);

long days = duration.toDays();
long hours = duration.minusDays(days).toHours();
long minutes = duration.minusDays(days).minusHours(hours).toMinutes();

System.out.println("Diferencia: " + days + " días " +
    hours + " horas " + minutes + " minutos");

7. Particularidades al trabajar con ZonedDateTime e Instant

  • La diferencia entre dos ZonedDateTime en zonas distintas se calcula según el tiempo absoluto, no según el tiempo «humano» en cada zona.
  • El cambio de horario de verano/invierno puede influir en la diferencia en horas entre fechas.

Ejemplo: diferencia entre ZonedDateTime

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

ZonedDateTime MinskTime = ZonedDateTime.of(2025, 6, 1, 12, 0, 0, 0, ZoneId.of("Europe/Minsk"));
ZonedDateTime nyTime = ZonedDateTime.of(2025, 6, 1, 5, 0, 0, 0, ZoneId.of("America/New_York"));

Duration diff = Duration.between(nyTime, MinskTime);
System.out.println("Diferencia: " + diff.toHours() + " horas");

8. Errores típicos al hacer cálculos con fechas y horas

Error n.º 1: confundir Period y Duration.
Si intentas usar Duration para LocalDate, obtendrás una excepción. Para fechas usa Period, para el tiempo — Duration.

Error n.º 2: no tener en cuenta los husos horarios.
Si comparas fechas y horas en diferentes husos horarios, puedes obtener resultados inesperados. Es mejor unificar todo a un mismo huso o usar Instant.

Error n.º 3: esperar que los métodos plus/minus modifiquen el objeto.
¡Todos los objetos de java.time son inmutables! No olvides asignar el resultado a una variable nueva (por ejemplo, today = today.plusDays(1)).

Error n.º 4: usar getDays() de Period y pensar que es el total de días.
En realidad, son solo los días residuales tras restar años y meses. Para el total de días usa ChronoUnit.DAYS.between().

Error n.º 5: comparar objetos de tipos distintos.
Los métodos isBefore, isAfter, isEqual solo funcionan para objetos del mismo tipo (por ejemplo, LocalDate con LocalDate).

1
Tarea
JAVA 25 SELF, nivel 13, lección 5
Bloqueada
Cuenta regresiva para la celebración 🎉
Cuenta regresiva para la celebración 🎉
1
Tarea
JAVA 25 SELF, nivel 13, lección 5
Bloqueada
Máquina del tiempo: comprobación de si ha llegado una fecha 🕰️
Máquina del tiempo: comprobación de si ha llegado una fecha 🕰️
1
Tarea
JAVA 25 SELF, nivel 13, lección 5
Bloqueada
Gestión de proyectos: ¿cuántos días quedan para la fecha límite? 🗓️
Gestión de proyectos: ¿cuántos días quedan para la fecha límite? 🗓️
1
Tarea
JAVA 25 SELF, nivel 13, lección 5
Bloqueada
Agencia inmobiliaria: cálculo de la edad del edificio 🏡
Agencia inmobiliaria: cálculo de la edad del edificio 🏡
1
Cuestionario/control
Fechas y hora, nivel 13, lección 5
No disponible
Fechas y hora
Fechas, hora y zonas horarias
Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION