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

Проверка того, совпадают ли две даты Java в один и тот же день

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

1. Обзор

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

Мы начнем с рассмотрения решений, использующих ядро Java, а именно функции Java 8, а затем рассмотрим пару альтернатив, предшествующих Java 8.

В завершение мы также рассмотрим некоторые внешние библиотеки — Apache Commons Lang, Joda-Time и Date4J .

2. Ядро Java

Класс Date представляет конкретный момент времени с точностью до миллисекунды . Чтобы узнать, содержат ли два объекта Date один и тот же день, нам нужно проверить, является ли год-месяц-день одинаковым для обоих объектов, и отбросить аспект времени .

2.1. Использование локальной даты

С новым API Date-Time в Java 8 мы можем использовать объект LocalDate . Это неизменяемый объект, представляющий дату без времени.

Давайте посмотрим, как мы можем проверить, имеют ли два объекта Date один и тот же день, используя этот класс:

public static boolean isSameDay(Date date1, Date date2) {
LocalDate localDate1 = date1.toInstant()
.atZone(ZoneId.systemDefault())
.toLocalDate();
LocalDate localDate2 = date2.toInstant()
.atZone(ZoneId.systemDefault())
.toLocalDate();
return localDate1.isEqual(localDate2);
}

В этом примере мы преобразовали оба объекта Date в LocalDate , используя часовой пояс по умолчанию . После преобразования нам просто нужно проверить, равны ли объекты LocalDate , используя метод isEqual .

Следовательно, используя этот подход, мы сможем определить, содержат ли два объекта Date один и тот же день.

2.2. Использование мгновенного

В приведенном выше примере мы использовали Instant в качестве промежуточного объекта при преобразовании объектов Date в объекты LocalDate . Instant , представленный в Java 8, представляет определенный момент времени .

Мы можем напрямую обрезать объекты Instant до единицы DAYS , которая устанавливает значения поля времени равными нулю, а затем мы можем их сравнить:

public static boolean isSameDayUsingInstant(Date date1, Date date2) {
Instant instant1 = date1.toInstant()
.truncatedTo(ChronoUnit.DAYS);
Instant instant2 = date2.toInstant()
.truncatedTo(ChronoUnit.DAYS);
return instant1.equals(instant2);
}

2.3. Использование SimpleDateFormat

Начиная с ранних версий Java, мы могли использовать класс SimpleDateFormat для преобразования между представлениями объекта Date и String . Этот класс поставляется с поддержкой преобразования с использованием множества шаблонов. В нашем случае мы будем использовать шаблон «ггггММдд» .

Используя это, мы отформатируем дату, преобразуем ее в объект String , а затем сравним их, используя стандартный метод equals :

public static boolean isSameDay(Date date1, Date date2) {
SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMdd");
return fmt.format(date1).equals(fmt.format(date2));
}

2.4. Использование календаря

Класс Calendar предоставляет методы для получения значений различных единиц даты и времени для определенного момента времени.

Во-первых, нам нужно создать экземпляр календаря и установить время объектов календаря , используя каждую из предоставленных дат. Затем мы можем запросить и сравнить атрибуты Year-Month-Day по отдельности , чтобы выяснить, имеют ли объекты Date один и тот же день:

public static boolean isSameDay(Date date1, Date date2) {
Calendar calendar1 = Calendar.getInstance();
calendar1.setTime(date1);
Calendar calendar2 = Calendar.getInstance();
calendar2.setTime(date2);
return calendar1.get(Calendar.YEAR) == calendar2.get(Calendar.YEAR)
&& calendar1.get(Calendar.MONTH) == calendar2.get(Calendar.MONTH)
&& calendar1.get(Calendar.DAY_OF_MONTH) == calendar2.get(Calendar.DAY_OF_MONTH);
}

3. Внешние библиотеки

Теперь, когда мы хорошо понимаем, как сравнивать объекты Date с помощью нового и старого API, предлагаемых ядром Java, давайте взглянем на некоторые внешние библиотеки.

3.1. Apache Commons Lang DateUtils

Класс DateUtils предоставляет множество полезных утилит, упрощающих работу с устаревшими объектами Calendar и Date .

Артефакт Apache Commons Lang доступен на Maven Central :

<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
</dependency>

Затем мы можем просто использовать метод isSameDay из DateUtils :

DateUtils.isSameDay(date1, date2);

3.2. Библиотека Джода-Время

Альтернативой базовой библиотеке Java Date and Time является Joda-Time . Эта широко используемая библиотека служит отличной заменой при работе с датой и временем .

Артефакт можно найти на Maven Central :

<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.10</version>
</dependency>

В этой библиотеке org.joda.time.LocalDate представляет дату без времени . Следовательно, мы можем создать объекты LocalDate из объектов java.util.Date , а затем сравнить их:

public static boolean isSameDay(Date date1, Date date2) {
org.joda.time.LocalDate localDate1 = new org.joda.time.LocalDate(date1);
org.joda.time.LocalDate localDate2 = new org.joda.time.LocalDate(date2);
return localDate1.equals(localDate2);
}

3.3. Библиотека Date4J

Date4j также предоставляет прямую и простую реализацию, которую мы можем использовать.

Кроме того, он также доступен в Maven Central :

<dependency>
<groupId>com.darwinsys</groupId>
<artifactId>hirondelle-date4j</artifactId>
<version>1.5.1</version>
</dependency>

Используя эту библиотеку, нам нужно создать объект DateTime из объекта java.util.Date . Затем мы можем просто использовать метод isSameDayAs :

public static boolean isSameDay(Date date1, Date date2) {
DateTime dateObject1 = DateTime.forInstant(date1.getTime(), TimeZone.getDefault());
DateTime dateObject2 = DateTime.forInstant(date2.getTime(), TimeZone.getDefault());
return dateObject1.isSameDayAs(dateObject2);
}

4. Вывод

В этом кратком руководстве мы рассмотрели несколько способов проверки того, содержат ли два объекта java.util.Date один и тот же день.

Как всегда, полный исходный код статьи доступен на GitHub .