Автор оригинала: Drazen Nikolic.
1. введение
В этом уроке мы сосредоточимся на том, как сравнивать даты с помощью API даты и времени Java 8 . Мы рассмотрим различные методы, чтобы проверить, равны ли две даты и как сравнивать даты.
2. Сравнение Дат
Основным способом выражения даты в Java является LocalDate . Давайте рассмотрим два экземпляра Локальных данных объекта, представляющих 10 августа 2019 года и 1 июля 2019 года:
LocalDate firstDate = LocalDate.of(2019, 8, 10); LocalDate secondDate = LocalDate.of(2019, 7, 1);
Мы собираемся сравнить два Локальных объекта данных с помощью методов isAfter() , isBefore () и isEqual (), а также equals() и compareTo() .
Мы используем метод is After () , чтобы проверить, находится ли экземпляр данных после другой указанной даты. Таким образом, следующее утверждение JUnit пройдет:
assertThat(firstDate.isAfter(secondDate), is(true));
Аналогично, метод is Before() проверяет, находится ли экземпляр date до другой указанной даты:
assertThat(firstDate.isBefore(secondDate), is(false));
Метод Равен() проверяет, представляет ли дата ту же точку на локальной временной шкале, что и другая указанная дата:
assertThat(firstDate.isEqual(firstDate), is(true)); assertThat(firstDate.isEqual(secondDate), is(false));
2.1. Сравнение Дат С Использованием Сопоставимого интерфейса
Метод equals() даст тот же результат , что и метод is Equal () , но только в том случае, если переданный аргумент имеет тот же тип (в данном случае LocalDate ):
assertThat(firstDate.equals(secondDate), is(false));
Вместо этого метод isEqual() можно использовать для сравнения с объектами другого типа, такими как Японская дата , ThaiBuddhistDate и т. Д.
Мы можем сравнить два экземпляра даты с помощью метода compareTo () , как определено интерфейсом Comparable :
assertThat(firstDate.compareTo(secondDate), is(1)); assertThat(secondDate.compareTo(firstDate), is(-1));
3. Сравнение экземпляров данных, содержащих компонент Времени
В этом разделе будет объяснено, как сравнить два экземпляра LocalDateTime . LocalDateTime экземпляры содержат дату, а также компонент времени.
Аналогично Local Date , мы сравниваем два экземпляра LocalDateTime с методами isAfter() , isBefore() и is Equal() . Кроме того, equals() и compareTo() могут использоваться аналогичным образом, как описано для LocalDate.
Аналогично, мы можем использовать те же методы для сравнения двух экземпляров ZonedDateTime . Давайте сравним 8:00 по местному времени в Нью-Йорке и 14:00 по местному времени в Берлине в один и тот же день:
ZonedDateTime timeInNewYork = ZonedDateTime.of(2019, 8, 10, 8, 0, 0, 0, ZoneId.of("America/New_York")); ZonedDateTime timeInBerlin = ZonedDateTime.of(2019, 8, 10, 14, 0, 0, 0, ZoneId.of("Europe/Berlin")); assertThat(timeInNewYork.isAfter(timeInBerlin), is(false)); assertThat(timeInNewYork.isBefore(timeInBerlin), is(false)); assertThat(timeInNewYork.isEqual(timeInBerlin), is(true));
Хотя оба экземпляра ZonedDateTime представляют один и тот же момент времени, они не представляют одинаковые объекты Java. Они имеют разные LocalDateTime и ZoneId поля внутри:
assertThat(timeInNewYork.equals(timeInBerlin), is(false)); assertThat(timeInNewYork.compareTo(timeInBerlin), is(-1));
4. Дополнительные Сравнения
Давайте создадим простой служебный класс для немного более сложных сравнений.
Во-первых, мы проверим, находятся ли экземпляры LocalDateTime и Local Data в один и тот же день:
public static boolean isSameDay(LocalDateTime timestamp, LocalDate localDateToCompare) { return timestamp.toLocalDate().isEqual(localDateToCompare); }
Во-вторых, мы проверим, находятся ли два экземпляра LocalDateTime в один и тот же день:
public static boolean isSameDay(LocalDateTime timestamp, LocalDateTime timestampToCompare) { return timestamp.truncatedTo(DAYS) .isEqual(timestampToCompare.truncatedTo(DAYS)); }
Метод truncated To(TemporalUnit) усекает дату на заданном уровне , которая в нашем примере является днем.
В-третьих, мы можем реализовать сравнение на уровне часа:
public static boolean isSameHour(LocalDateTime timestamp, LocalDateTime timestampToCompare) { return timestamp.truncatedTo(HOURS) .isEqual(timestampToCompare.truncatedTo(HOURS)); }
Наконец, аналогичным образом мы можем проверить, происходят ли два экземпляра ZonedDateTime в течение одного и того же часа:
public static boolean isSameHour(ZonedDateTime zonedTimestamp, ZonedDateTime zonedTimestampToCompare) { return zonedTimestamp.truncatedTo(HOURS) .isEqual(zonedTimestampToCompare.truncatedTo(HOURS)); }
Мы видим, что два объекта ZonedDateTime на самом деле происходят в течение одного и того же часа, даже если их местное время отличается (8:30 и 14:00 соответственно):
ZonedDateTime zonedTimestamp = ZonedDateTime.of(2019, 8, 10, 8, 30, 0, 0, ZoneId.of("America/New_York")); ZonedDateTime zonedTimestampToCompare = ZonedDateTime.of(2019, 8, 10, 14, 0, 0, 0, ZoneId.of("Europe/Berlin")); assertThat(DateTimeComparisonUtils. isSameHour(zonedTimestamp, zonedTimestampToCompare), is(true));
5. Сравнение в старом API даты Java
До Java 8 нам приходилось использовать java.util.Дата и java.util.Календарь классы для манипулирования информацией о дате/времени. Дизайн старого API даты Java имеет много недостатков, таких как сложность и не потокобезопасность. java.util.Экземпляр Date представляет собой “момент времени” , а не реальную дату.
Одним из решений было использование библиотеки времени Joda. С момента выпуска Java 8 рекомендуется перейти на API даты и времени Java 8 .
Аналогично LocalDate и LocalDateTime , оба java.util.Дата и java.util.Объекты календаря имеют после() , до() , compareTo() и equals() методы сравнения двух экземпляров даты . Даты сравниваются как мгновения во времени, на уровне миллисекунды:
Date firstDate = toDate(LocalDateTime.of(2019, 8, 10, 0, 00, 00)); Date secondDate = toDate(LocalDateTime.of(2019, 8, 15, 0, 00, 00)); assertThat(firstDate.after(secondDate), is(false)); assertThat(firstDate.before(secondDate), is(true)); assertThat(firstDate.compareTo(secondDate), is(-1)); assertThat(firstDate.equals(secondDate), is(false));
Для более сложных сравнений мы можем использовать DateUtils из библиотеки Apache Commons Lang . Этот класс содержит множество удобных методов для работы с объектами Дата и Календарь :
public static boolean isSameDay(Date date, Date dateToCompare) { return DateUtils.isSameDay(date, dateToCompare); } public static boolean isSameHour(Date date, Date dateToCompare) { return DateUtils.truncatedEquals(date, dateToCompare, Calendar.HOUR); }
Чтобы сравнить объекты даты, происходящие из разных API, мы должны сначала выполнить правильное преобразование и только затем применить сравнение. Мы можем найти более подробную информацию в нашем Преобразовании данных в локальные данные или LocalDateTime и обратно учебнике.
6. Заключение
В этой статье мы рассмотрели различные способы сравнения экземпляров данных в Java.
Классы даты и времени Java 8 имеют богатые API для сравнения дат, с или без времени и часовых поясов. Мы также видели, как сравнивать даты по детализации дня, часа, минуты и т. Д.
Все фрагменты кода, упомянутые в статье, включая дополнительные примеры, доступны на GitHub .