Cómo obtener el número de días entre fechas en Java

En este tutorial, aprenda cómo calcular/obtener la cantidad de días entre dos fechas en Java, ya sean objetos LocalDate o cadenas, usando ChronoUnit, Joda-Time, Period, etc.

Introducción

La mayoría de las veces nos encontramos contando el número de días desde o hasta una fecha en particular. Afortunadamente, hacer exactamente eso en Java no es muy difícil, y también hay bastantes formas de hacerlo.

Entonces, en este artículo, veremos cómo obtener el número de días entre dos fechas en Java.

Encontrar la diferencia entre dos fechas anteriores a Java 8 {#encontrar la diferencia entre dos fechas anteriores a Java8}

Esta es una de las formas más fáciles y sencillas de calcular la diferencia de días entre dos fechas. Para hacerlo, necesitamos tener dos objetos Date. Usando getTime() de la clase java.util.Date, obtendremos el número de milisegundos desde el 1 de enero de 1970, 00:00:00 GMT representado por una Date específica objeto.

{.icon aria-hidden=“true”}

Nota: Este tiempo específico tampoco es una coincidencia, ya que a menudo se lo conoce como el comienzo de la Época UNIX o Tiempo UNIX.

Después de obtener el tiempo en milisegundos, obtendremos la diferencia entre dos valores restándolos y convirtiendo el nuevo valor en días, ya sea manualmente (haciendo un cálculo simple) o usando el método TimeUnit.DAYS.convert de * java.util.concurrent.TimeUnit*.

Podemos obtener fechas como un objeto Date o String. En el segundo caso, necesitamos convertir un String en Date usando el método parse de la Clase SimpleDateFormat.

Calculemos el número de días de dos fechas de ejemplo:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
Date dateBefore = new Date(2022, Calendar.APRIL, 21);
Date dateAfter = new Date(2022, Calendar.APRIL, 25);

long dateBeforeInMs = dateBefore.getTime();
long dateAfterInMs = dateAfter.getTime();

long timeDiff = Math.abs(dateAfterInMs - dateBeforeInMs);

long daysDiff = TimeUnit.DAYS.convert(timeDiff, TimeUnit.MILLISECONDS);
// Alternatevly: 
// int daysDiff = (int) (timeDiff / (1000 * 60 * 60 * 24));
System.out.println(" The number of days between dates: " + daysDiff);

Dado que hay cuatro días entre nuestras fechas de ejemplo, el código anterior producirá el siguiente resultado:

1
The number of days between dates: 4

Como se mencionó anteriormente, si hemos usado un objeto ‘Cadena’ en lugar de un objeto ‘Fecha’, primero debemos convertirlo para que sea utilizable. Para convertir una ‘Cadena’ en una ‘Fecha’, primero debemos definir qué formato de fecha usaremos para analizar los valores correctamente. En nuestro ejemplo, usaremos el formato MM/dd/yyyy. Después de eso, analizamos String a Date y hacemos lo mismo que hicimos en el ejemplo anterior:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
try {
// Convert `String` to `Date`
    SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy", Locale.ENGLISH);
    Date dateBefore = sdf.parse("04/21/2022");
    Date dateAfter = sdf.parse("04/25/2022");

// Calculate the number of days between dates
    long timeDiff = Math.abs(dateAfter.getTime() - dateBefore.getTime());
    long daysDiff = TimeUnit.DAYS.convert(timeDiff, TimeUnit.MILLISECONDS);
    System.out.println("The number of days between dates: " + daysDiff);
}catch(Exception e){
    e.printStackTrace();
}

Primero definimos un nuevo SimpleDateFormat para saber cómo analizar las fechas dadas a través de String, después de lo cual usamos el método parse para hacer precisamente eso. Lo único a lo que debemos prestar atención aquí es que debemos rodear esta parte del código con un bloque try-catch, ya que el método parse puede causar un error al romper nuestro programa. Finalmente, después de que hayamos calculado la diferencia de tiempo, aplicamos de nuevo el método TimeUnit.DAYS.convert para convertirlo a días y producir el siguiente resultado:

1
The number of days between dates: 4

Hallar la diferencia entre dos fechas usando java.time.temporal.ChronoUnit

ChronoUnit es una enumeración que implementa la interfaz TemporalUnit, que proporciona las unidades estándar utilizadas en Java Date Time API (esencialmente, un conjunto estándar de unidades de períodos de fecha). Este conjunto de unidades proporciona acceso basado en unidades para manipular una fecha, hora o fecha-hora.

ChronoUnit tiene solo unos pocos métodos, y el que más nos interesa es el método beth between(). Este método toma dos objetos ‘Temporales’ y calcula la cantidad de tiempo entre ellos. Los puntos inicial y final deben ser de tipos compatibles. La implementación convertirá el segundo tipo en una instancia del primer tipo antes de calcular la cantidad. El cálculo devuelve un número entero, que representa el número de unidades completas entre los dos temporales.

{.icon aria-hidden=“true”}

Nota: El resultado será negativo si la fecha de finalización es anterior a la fecha de inicio.

Hay dos formas diferentes de usar el método entre(). La primera es invocar este método directamente. El segundo es usar Temporal.until(Temporal, TemporalUnit) que lo invoca implícitamente:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
try {
    LocalDate dateBefore = LocalDate.parse("2022-04-21");
    LocalDate dateAfter = LocalDate.parse("2022-04-25");

    // Approach 1
    long daysDiff = ChronoUnit.DAYS.between(dateBefore, dateAfter);
    System.out.println("The number of days between dates: " + daysDiff);
    
    // Approach 2
    long daysDiff = dateBefore.until(dateAfter, ChronoUnit.DAYS);
    System.out.println("The number of days between dates: " + daysDiff);
    
}catch(Exception e){
    e.printStackTrace();
}

Ambos producen el mismo resultado:

1
The number of days between dates: 4

Hallar la diferencia entre dos fechas usando java.Time.Period

La clase Período es una clase basada en fechas, lo que significa que modela una cantidad (cantidad) de tiempo en términos de años, meses y días; por ejemplo, '3 años, 5 meses y 7 días' . Tiene un equivalente basado en el tiempo, la clase Duración, que modela la cantidad de tiempo en términos de segundos y nanosegundos.

Las duraciones y los períodos difieren en su tratamiento del horario de verano cuando se agregan a ZonedDateTime. Una ‘Duración’ agregará un número exacto de segundos, por lo que la duración de un día siempre es exactamente 24 horas. Por el contrario, un Período agregará un día conceptual, tratando de mantener la hora local.

La clase Period tiene un método between() - al igual que ChronoUnit discutido anteriormente. Este método toma dos objetos LocalDate, uno representa la fecha de inicio y el segundo es la fecha de finalización. Devuelve un Período que consiste en el número de años, meses y días entre dos fechas. Es importante tener en cuenta que la fecha de inicio está incluida, mientras que la fecha de finalización no lo está.

Veamos un ejemplo de cómo podemos usar este método:

1
2
3
4
5
6
7
LocalDate dateBefore = LocalDate.of(2022, 4, 21);
LocalDate dateAfter = LocalDate.of(2022, 4, 25);

Period period = Period.between(dateBefore, dateAfter);
long daysDiff = Math.abs(period.getDays());

System.out.println(" The number of days between dates: " + daysDiff);

Esto funciona bien y producirá el mismo resultado que todos los ejemplos anteriores que tuvimos. Sin embargo, hay un gran problema con este enfoque si desea calcular el tiempo de los días entre los meses:

1
2
LocalDate dateBefore = LocalDate.of(2022, 2, 21);
LocalDate dateAfter = LocalDate.of(2022, 4, 25);

Si calculamos la diferencia entre estas dos fechas, la respuesta esperada debería ser 63 días. Sin embargo, el resultado que obtenemos nuevamente es de 4 días. El razonamiento detrás de esto es que nuevamente: los períodos incluyen la cantidad de años, meses y días como entidades separadas. No podemos "resumir" los meses y años en días de forma nativa, por lo que tendría que crear un método adicional para eso:

1
2
3
4
5
6
7
 static long getDayDiff(Period period) {
    long years = period.getYears();
    long months = period.getMonths();
    long days = period.getDays();

    return (years*365)+(months*30)+days;
}

Sin embargo, esto sigue siendo solo una aproximación que no tiene en cuenta los años bisiestos, ni si un mes tiene 30 o 31 días. Todas las cláusulas if y comprobaciones pueden volverse bastante detalladas rápidamente, por lo que se recomienda encarecidamente apegarse al método entre() para obtener el número de días entre fechas.

Hallar la diferencia entre dos fechas usando Joda-Time

Se sabía que las clases de fecha y hora estándar anteriores a Java 8 eran deficientes, por lo que ‘Joda-Time’ se convirtió en la biblioteca de fecha y hora estándar que se usaba más ampliamente en ese momento. El diseño permite múltiples sistemas de calendario, al mismo tiempo que proporciona una API simple. Se incluyeron la mayoría de los sistemas de calendario, así como clases de apoyo para zonas horarias, duración, formato y análisis.

{.icon aria-hidden=“true”}

Nota: Esta sección se agregó para los sistemas heredados que aún usan Joda-Time, en lugar de la nueva API de Fecha/Hora. Si está utilizando una versión más nueva de Java, es preferible, más fácil y más eficaz no incluir nuevas dependencias.

Agregar Joda-Time a nuestro proyecto requiere agregar la siguiente dependencia de Maven Central:

1
2
3
4
5
<dependency>
    <groupId>joda-time</groupId>
    <artifactId>joda-time</artifactId>
    <version>2.10.14</version>
</dependency>

No profundizaremos en todo lo que ofrece la biblioteca Joda-Time, y si está más interesado, puede consultar el [Sitio web de Joda-Time] oficial (https://www.joda. org/joda-time/).

Ahora que hemos agregado la biblioteca a nuestro proyecto, obtener la diferencia entre las fechas es muy simple y no difiere en absoluto de los enfoques anteriores:

1
2
3
4
5
org.joda.time.LocalDate dateBefore = org.joda.time.LocalDate.parse("2022-04-21");
org.joda.time.LocalDate dateAfter = org.joda.time.LocalDate.parse("2022-04-25");

long daysDiff = Math.abs(Days.daysBetween(dateBefore, dateAfter).getDays());
System.out.println(" The number of days between dates: " + daysDiff);

Aunque útil, esta biblioteca está prácticamente "superada" por la revisión de cómo se formatea la hora y las fechas en Java 8, y prácticamente no ofrece beneficios en comparación con los enfoques anteriores discutidos. Sin embargo, si por alguna razón usa una versión anterior a Java 8, esta es la mejor manera de hacerlo.

Conclusión

En este artículo hemos echado un vistazo a cómo hacer una de las tareas más básicas en la programación: encontrar el número de días entre dos fechas. En primer lugar, hicimos esto de la manera más simple posible, y luego examinamos varios enfoques alternativos: la enumeración ChronoUnit, las clases Duration y Period de java.time. Finalmente, hemos echado un vistazo a cómo calcular el número de días entre dos fechas usando una biblioteca externa muy popular como Joda-Time, para un enfoque mucho más elegante para resolver este problema. ma.