Agregar horas a una fecha en Java

1. Información general

Antes de Java 8, java.util.Date era una de las clases más utilizadas para representar valores de fecha y hora en Java.

Luego, Java 8 introdujo java.time.LocalDateTime y java.time.ZonedDateTime. Java 8 también nos permite representar un tiempo específico en la línea de tiempo usando java.time.Instant.

En este tutorial, aprenderemos a sumar o restar n horas de una fecha y hora determinada en Java . Primero veremos algunas clases estándar de Java relacionadas con la fecha y la hora, y luego mostraremos algunas opciones de terceros.

Para obtener más información sobre Java 8 DateTime API, le sugerimos que lea este artículo.

2. java.util.Date

Si usamos Java 7 o versiones anteriores, podemos usar las clases java.util.Date y java.util.Calendar para la mayor parte del manejo relacionado con la fecha y la hora.

Veamos cómo agregar n horas a un objeto Date dado :

public Date addHoursToJavaUtilDate(Date date, int hours) { Calendar calendar = Calendar.getInstance(); calendar.setTime(date); calendar.add(Calendar.HOUR_OF_DAY, hours); return calendar.getTime(); }

Tenga en cuenta que Calendar.HOUR_OF_DAY se refiere a un reloj de 24 horas .

El método anterior devuelve un nuevo objeto Date , cuyo valor sería (fecha + horas) o (fecha - horas) , dependiendo de si pasamos un valor positivo o negativo de horas respectivamente.

Supongamos que tenemos una aplicación Java 8, pero queremos seguir trabajando con las instancias java.util.Date .

Para tal caso, podemos optar por adoptar el siguiente enfoque alternativo:

  1. Utilice el método java.util.Date toInstant () para convertir un objeto Date en una instancia java.time.Instant
  2. Agregue una duración específica al objeto java.time.Instant usando el método plus ()
  3. Recupere nuestra instancia java.util.Date pasando el objeto java.time.Instant al método java.util.Date.from ()

Echemos un vistazo rápido a este enfoque:

@Test public void givenJavaUtilDate_whenUsingToInstant_thenAddHours() { Date actualDate = new GregorianCalendar(2018, Calendar.JUNE, 25, 5, 0) .getTime(); Date expectedDate = new GregorianCalendar(2018, Calendar.JUNE, 25, 7, 0) .getTime(); assertThat(Date.from(actualDate.toInstant().plus(Duration.ofHours(2)))) .isEqualTo(expectedDate); }

Sin embargo, tenga en cuenta que siempre se recomienda utilizar la nueva API DateTime para todas las aplicaciones en Java 8 o versiones superiores.

3. java.time.LocalDateTime / ZonedDateTime

En Java 8 o posterior, agregar horas a una instancia java.time.LocalDateTime o java.time.ZonedDateTime es bastante sencillo y hace uso del método plusHours () :

@Test public void givenLocalDateTime_whenUsingPlusHours_thenAddHours() { LocalDateTime actualDateTime = LocalDateTime .of(2018, Month.JUNE, 25, 5, 0); LocalDateTime expectedDateTime = LocalDateTime. of(2018, Month.JUNE, 25, 10, 0); assertThat(actualDateTime.plusHours(5)).isEqualTo(expectedDateTime); }

¿Y si deseamos restar algunas horas?

Pasar un valor negativo de horas al método plusHours () estaría bien. Sin embargo, se recomienda utilizar el método minusHours () :

@Test public void givenLocalDateTime_whenUsingMinusHours_thenSubtractHours() { LocalDateTime actualDateTime = LocalDateTime .of(2018, Month.JUNE, 25, 5, 0); LocalDateTime expectedDateTime = LocalDateTime .of(2018, Month.JUNE, 25, 3, 0); assertThat(actualDateTime.minusHours(2)).isEqualTo(expectedDateTime); }

Los métodos plusHours () y minusHours () en java.time.ZonedDateTime funcionan exactamente de la misma manera.

4. java.time.Instant

Como sabemos, java.time.Instant introducido en Java 8 DateTime API representa un momento específico en la línea de tiempo.

Para agregar algunas horas a un objeto Instant , podemos usar su método plus () con un java.time.temporal.TemporalAmount :

@Test public void givenInstant_whenUsingAddHoursToInstant_thenAddHours() { Instant actualValue = Instant.parse("2018-06-25T05:12:35Z"); Instant expectedValue = Instant.parse("2018-06-25T07:12:35Z"); assertThat(actualValue.plus(2, ChronoUnit.HOURS)) .isEqualTo(expectedValue); }

De manera similar, el método minus () se puede usar para restar un TemporalAmount específico .

5. Apache Commons DateUtils

La clase DateUtils de la biblioteca Apache Commons Lang expone un método addHours () estático :

public static Date addHours(Date date, int amount)

El método toma un objeto java.util.Date junto con una cantidad que deseamos agregarle, cuyo valor podría ser positivo o negativo.

Se devuelve un nuevo objeto java.util.Date como resultado:

@Test public void givenJavaUtilDate_whenUsingApacheCommons_thenAddHours() { Date actualDate = new GregorianCalendar(2018, Calendar.JUNE, 25, 5, 0) .getTime(); Date expectedDate = new GregorianCalendar(2018, Calendar.JUNE, 25, 7, 0) .getTime(); assertThat(DateUtils.addHours(actualDate, 2)).isEqualTo(expectedDate); }

La última versión de Apache Commons Lang está disponible en Maven Central.

6. Hora de Joda

Joda Time es una alternativa a la API DateTime de Java 8 y proporciona sus propias implementaciones DateTime .

La mayoría de sus clases relacionadas con DateTime exponen los métodos plusHours () y minusHours () para ayudarnos a sumar o restar un número determinado de horas de un objeto DateTime .

Veamos un ejemplo:

@Test public void givenJodaDateTime_whenUsingPlusHoursToDateTime_thenAddHours() { DateTime actualDateTime = new DateTime(2018, 5, 25, 5, 0); DateTime expectedDateTime = new DateTime(2018, 5, 25, 7, 0); assertThat(actualDateTime.plusHours(2)).isEqualTo(expectedDateTime); }

Podemos comprobar fácilmente la última versión disponible de Joda Time en Maven Central.

7. Conclusión

En este tutorial, cubrimos varias formas de sumar o restar una cantidad determinada de horas de los valores estándar de fecha y hora de Java.

También analizamos algunas bibliotecas de terceros como alternativa. Como de costumbre, el código fuente completo está disponible en GitHub.