Adicionar horas a uma data em Java

Adicionar horas a uma data em Java

1. Visão geral

Antes do Java 8,java.util.Date era uma das classes mais comumente usadas para representar valores de data e hora em Java.

Em seguida, o Java 8 introduziujava.time.LocalDateTimeejava.time.ZonedDateTime.. O Java 8 também nos permite representar um tempo específico na linha do tempo usandojava.time.Instant.

Neste tutorial, aprenderemos aadd or subtract n hours from a given date-time in Java. Veremos primeiro algumas classes Java padrão relacionadas à data e hora e, em seguida, mostraremos algumas opções de terceiros.

Para saber mais sobre a API Java 8 DateTime, sugerimos a leitura dethis article.

2. java.util.Date

Se estivermos usando Java 7 ou inferior, podemos usar as classesjava.util.Dateejava.util.Calendar para a maioria dos procedimentos relacionados a data e hora.

Vamos ver como adicionarn horas a um determinado objetoDate:

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

Observe queCalendar.HOUR_OF_DAY is referring to a 24-hour clock.

O método acima retorna um novo objetoDate, o valor do qual seria(date + hours) ou(date – hours), dependendo se passamos um valor positivo ou negativo dehours respectivamente.

Suponha que temos um aplicativo Java 8, mas ainda queremos trabalhar do nosso jeito com instânciasjava.util.Date.

Nesse caso, podemos optar por seguir a seguinte abordagem alternativa:

  1. Use o métodojava.util.DatetoInstant() para converter um objetoDate em uma instânciajava.time.Instant

  2. Adicione umDuration específico ao objetojava.time.Instant usando o métodoplus()

  3. Recupere nossa instânciajava.util.Date passando o objetojava.time.Instant para o métodojava.util.Date.from()

Vamos dar uma olhada rápida nesta abordagem:

@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);
}

No entanto, observe queit’s always recommended to use the new DateTime API for all applications on Java 8 or higher versions.

3. java.time.LocalDateTime/ZonedDateTime

No Java 8 ou posterior, adicionar horas a uma instânciajava.time.LocalDateTime or java.time.ZonedDateTime é bastante simples e usa o métodoplusHours():

@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);
}

E se quisermos subtrair algumas horas?

Passar um valor negativo de horas para o métodoplusHours() seria suficiente. No entanto, é recomendado usar o métodominusHours():

@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);

}

Os métodosplusHours()eminusHours() emjava.time.ZonedDateTime funcionam exatamente da mesma maneira.

4. java.time.Instant

Como sabemos,java.time.Instant introduzido na API Java 8 DateTime representa um momento específico na linha do tempo.

Para adicionar algumas horas a um objetoInstant, podemos usar seu métodoplus() com umjava.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);
}

Da mesma forma, o métodominus() pode ser usado para subtrair umTemporalAmount específico.

5. Apache CommonsDateUtils

A classeDateUtils da biblioteca Apache Commons Lang expõe um métodostaticaddHours():

public static Date addHours(Date date, int amount)

O método recebe um objetojava.util.Date junto com umamount que desejamos adicionar a ele, cujo valor pode ser positivo ou negativo.

Um novo objetojava.util.Date é retornado 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);
}

A última versão deApache Commons Lang está disponível emMaven Central.

6. Hora de Joda

Joda Time é uma alternativa à API Java 8 DateTime e fornece suas próprias implementaçõesDateTime.

A maioria de suasDateTime classes relacionadas expõe os métodosplusHours()eminusHours() para nos ajudar a adicionar ou subtrair um determinado número de horas de um objetoDateTime.

Vejamos um exemplo:

@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 facilmente verificar a última versão disponível deJoda Time emMaven Central.

7. Conclusão

Neste tutorial, abordamos várias maneiras de adicionar ou subtrair um determinado número de horas dos valores de data e hora padrão do Java.

Também analisamos algumas bibliotecas de terceiros como uma alternativa. Como de costume, o código-fonte completo está disponívelover on GitHub.