Добавить часы к дате в Java

Добавить часы к дате в Java

1. обзор

До Java 8java.util.Date был одним из наиболее часто используемых классов для представления значений даты и времени в Java.

Затем в Java 8 были представленыjava.time.LocalDateTime иjava.time.ZonedDateTime.. Java 8 также позволяет нам представлять конкретное время на временной шкале с помощьюjava.time.Instant..

В этом руководстве мы научимсяadd or subtract n hours from a given date-time in Java. Сначала мы рассмотрим некоторые стандартные классы Java, связанные с датой и временем, а затем продемонстрируем несколько сторонних вариантов.

Чтобы узнать больше об API Java 8 DateTime, мы рекомендуем прочитатьthis article.

2. java.util.Dateс

Если мы используем Java 7 или ниже, мы можем использовать классыjava.util.Date иjava.util.Calendar для большей части обработки, связанной с датой и временем.

Давайте посмотрим, как добавитьn часов к заданному объектуDate:

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

Обратите внимание, чтоCalendar.HOUR_OF_DAY is referring to a 24-hour clock.

Вышеупомянутый метод возвращает новый объектDate, значение которого будет либо(date + hours), либо(date – hours), в зависимости от того, передаем ли мы положительное или отрицательное значениеhours соответственно.

Предположим, у нас есть приложение Java 8, но мы все же хотим работать с экземплярамиjava.util.Date.

Для такого случая мы можем выбрать следующий альтернативный подход:

  1. Используйте методjava.util.DatetoInstant() для преобразования объектаDate в экземплярjava.time.Instant

  2. Добавьте конкретныйDuration к объектуjava.time.Instant с помощью методаplus()

  3. Восстановите наш экземплярjava.util.Date, передав объектjava.time.Instant методуjava.util.Date.from()

Давайте быстро рассмотрим этот подход:

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

Однако обратите внимание, чтоit’s always recommended to use the new DateTime API for all applications on Java 8 or higher versions.

3. java.time.LocalDateTime/ZonedDateTimeс

В Java 8 и новее добавить часы к экземпляруjava.time.LocalDateTime or java.time.ZonedDateTime довольно просто и использовать метод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);
}

Что если мы хотим вычесть несколько часов?

Передача отрицательного значения часов методуplusHours() вполне подойдет. Однако рекомендуется использовать метод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);

}

МетодыplusHours() иminusHours() вjava.time.ZonedDateTime работают точно так же.

4. java.time.Instantс

Как мы знаем,java.time.Instant, представленный в Java 8 DateTime API, представляет определенный момент на временной шкале.

Чтобы добавить несколько часов к объектуInstant, мы можем использовать его методplus() с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);
}

Точно так же методminus() может использоваться для вычитания определенногоTemporalAmount.

5. Apache CommonsDateUtils

КлассDateUtils из библиотеки Apache Commons Lang предоставляет методstaticaddHours():

public static Date addHours(Date date, int amount)

Метод принимает объектjava.util.Date вместе сamount, которое мы хотим добавить к нему, значение которого может быть как положительным, так и отрицательным.

В результате возвращается новый объектjava.util.Date:

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

Последняя версияApache Commons Lang доступна наMaven Central.

6. Время йода

Joda Time является альтернативой Java 8 DateTime API и предоставляет собственные реализацииDateTime.

Большинство связанных с ним классовDateTime предоставляют методыplusHours() иminusHours(), чтобы помочь нам добавить или вычесть заданное количество часов из объектаDateTime.

Давайте посмотрим на пример:

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

Мы можем легко проверить последнюю доступную версиюJoda Time вMaven Central.

7. Заключение

В этом руководстве мы рассмотрели несколько способов добавления или вычитания заданного количества часов из стандартных значений даты и времени Java.

Мы также рассмотрели некоторые сторонние библиотеки в качестве альтернативы. Как обычно, доступен полный исходный кодover on GitHub.