Сравняване на дати в Java

1. Въведение

В този урок ще се съсредоточим върху това как да сравняваме дати, използвайки Java 8 API за дата и час. Ще се потопим в различни методи, за да проверим дали две дати са равни и как да сравним датите.

2. Сравняване на дати

Основният начин за изразяване на дата в Java е LocalDate . Нека разгледаме два екземпляра на обект LocalDate , представляващи 10 август 2019 г. и 1 юли 2019 г .:

LocalDate firstDate = LocalDate.of(2019, 8, 10); LocalDate secondDate = LocalDate.of(2019, 7, 1);

Ще сравним два обекта LocalDate, като използваме методите isAfter () , isBefore () и isEqual (), както и equals () и compareTo () .

Използваме метода isAfter () , за да проверим дали датният екземпляр е след другата посочена дата. Следователно следващото твърдение на JUnit ще премине:

assertThat(firstDate.isAfter(secondDate), is(true));

Аналогично методът isBefore () проверява дали екземплярът на датата е преди другата посочена дата:

assertThat(firstDate.isBefore(secondDate), is(false));

Методът isEqual () проверява дали датата представлява същата точка на локалната времева линия като друга посочена дата:

assertThat(firstDate.isEqual(firstDate), is(true)); assertThat(firstDate.isEqual(secondDate), is(false));

2.1. Сравняване на дата, като използвате Сравними интерфейс

Методът equals () ще даде същия резултат като isEqual () , но само ако предаденият аргумент е от същия тип (в случая LocalDate ):

assertThat(firstDate.equals(secondDate), is(false));

Методът isEqual () може да се използва вместо това за сравнение с обекти от различен тип, като JapaneseDate , ThaiBuddhistDate и др.

Можем да сравним два екземпляра на дата, като използваме метода compareTo () , както е дефиниран от сравнимия интерфейс:

assertThat(firstDate.compareTo(secondDate), is(1)); assertThat(secondDate.compareTo(firstDate), is(-1));

3. Сравняване на екземпляри за дата, съдържащи компонент на времето

Този раздел ще обясни как да сравнявате два екземпляра LocalDateTime . Екземплярите LocalDateTime съдържат датата, както и компонента за време.

Подобно на LocalDate , ние сравняваме два екземпляра LocalDateTime с методите isAfter () , isBefore () и isEqual () . Освен това, 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 и LocalDate са в един и същи ден:

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)); }

Методът truncatedTo (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.Date и java.util.Calendar за манипулиране на информация за дата / час. Дизайнът на стария Java Date API има много недостатъци, като например, че е сложен и не е безопасен за нишки. В java.util.Date инстанция представлява "специални случаи", а не реална дата.

Едно от решенията беше да се използва библиотеката Joda Time. След пускането на Java 8 се препоръчва да се мигрира към API за дата / час на Java 8.

Подобно на LocalDate и LocalDateTime , и обектите java.util.Date и java.util.Calendar имат след () , преди () , 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, първо трябва да направим правилно преобразуване и едва след това да приложим сравнението. Можем да намерим повече подробности в нашия урок за Преобразуване на дата в LocalDate или LocalDateTime и Back.

6. Заключение

В тази статия разгледахме различни начини за сравняване на дати в Java.

Класовете Java 8 Date / Time имат богати API за сравняване на дати, със или без време и часови зони. Виждали сме също как да сравняваме датите по детайлността на ден, час, минута и т.н.

Всички кодови фрагменти, споменати в статията, включително допълнителни примери, са достъпни в GitHub.