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 .