Перейти к основному содержимому

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

· 4 мин. чтения

1. Обзор

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

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

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

Чтобы узнать больше об Java 8 DateTime API, мы бы посоветовали прочитать эту статью .

2. java.util.Дата

Если мы используем 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 относится к 24-часовому формату времени .

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

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

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

  1. Используйте метод java.util.Date toInstant() для преобразования объекта Date в экземпляр java.time.Instant.
  2. Добавьте определенную длительность к объекту 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);
}

Однако обратите внимание, что всегда рекомендуется использовать новый API DateTime для всех приложений на Java 8 или более поздних версиях.

3. java.time.LocalDateTime/ZonedDateTime

В Java 8 или более поздней версии добавление часов к экземпляру java.time.LocalDateTime или 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 Commons DateUtils

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

public static Date addHours(Date date, int amount)

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

В качестве результата возвращается новый объект 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.

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