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 .
В таком случае мы можем выбрать следующий альтернативный подход:
- Используйте метод
java.util.Date
toInstant()
для преобразования объектаDate
в экземплярjava.time.Instant.
- Добавьте определенную
длительность
к объектуjava.time.Instant,
используя метод plus() .
- Восстановите наш экземпляр
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 .