Вступление
Даты - это то, с чем мы сталкиваемся в повседневной жизни, независимо от того, используются ли они для календарей, планирования встреч или даже для запоминания дней рождения. Естественно, при работе с датами нам часто нужно знать, наступает ли определенная дата до или после другой, или они представляют одну и ту же календарную дату.
В этой статье мы рассмотрим, как сравнить две даты в Java .
Сравнение дат
Класс java.util.Date
представляет конкретный момент времени с
точностью до миллисекунды.
Он также имеет несколько встроенных методов, которые позволяют нам
сравнивать каждый Date
с другими экземплярами Date
Date.compareTo(Date date)
Date.equals(Object obj)
Date.before(Date when)
Date.after(Date when)
Примечание. Обратите внимание, что у Date
есть несколько
устаревших методов, включая обычный конструктор. Это старый класс,
замененный новым API даты / времени в Java 8, который рассматривается
сразу после этого раздела. Если вы используете Java 8+ , обратитесь к
разделам после этого .
Если вы используете версию до Java 8 , обратитесь к разделу Joda-Time .
Использование Date.compareTo ()
Как обычно с compareTo()
реализованными из Comparable
, этот метод
принимает другой Date
и сравнивает его со значением вызывающей Date
, возвращая 0
если значения равны , значение меньше 0
если дата
вызова предшествует дате аргумент и значение больше 0
если дата
вызова находится после аргумента.
В противном случае он NullPointerException
, если аргумент равен
null
.
Давайте создадим два Date
и сравним их:
Date date1 = new Date(2020, 1, 1);
Date date2 = new Date(2020, 1, 1);
int result = date1.compareTo(date2);
if(result == 0)
System.out.println("Both dates are equal");
else if (result < 0)
System.out.println("Date1 is before Date2");
else
System.out.println("Date1 is after Date2");
Выполнение этого кода приводит к:
Both dates are equal
Примечание. Опять же, это работает только для версий Java до Java
8 . С тех пор конструктор Date(int year, int month, int day)
устарел,
и остается только Date(long date)
.
Использование Date.before () , Date.after () и Date.equals ()
Метод after()
проверяет, находится ли вызывающая Date
после Date
аргумента, возвращая значения true
или false
соответственно.
before()
делает то же самое, проверяя, находится ли вызывающая Date
перед аргументом Date
.
Метод equals()
сравнивает две Dates
предмет равенства и возвращает
true
тогда и только тогда, когда аргумент не равен null
и является
Date
который представляет тот же момент времени, что и вызывающий
объект, иначе он вернет false
. Другими словами, он проверяет,
указывают ли ссылки на один и тот же объект в памяти.
Все три NullPointerException
если аргумент равен null
. Теперь мы
можем сделать предыдущий фрагмент кода более удобным и читаемым, если мы
заменим целочисленные проверки следующими методами:
SimpleDateFormat formatter = new SimpleDateFormat("YYYY-MM-dd");
Date date1 = new Date(); // Returns the current date and time
Date date2 = new Date(2021, 2, 12);
String formatted1 = formatter.format(date1);
String formatted2 = formatter.format(date2);
if(date1.equals(date2))
System.out.println("Both dates are equal");
else if(date1.after(date2))
System.out.println(String.format("%s comes after %s", formatted1, formatted2));
else if(date1.before(date2))
System.out.println(String.format("%s comes before %s", formatted1, formatted2));
Если вы не знакомы с SimpleDateFormat
, вы можете прочитать наше
Руководство по форматированию дат в Java с помощью
SimpleDateFormat.
Выполнение этого кода приводит к:
2021-03-24 comes after 2021-02-12
Сравнение LocalDates
Начиная с Java 8 , у нас были большие изменения относительно даты и времени. С существующим API даты и времени было много проблем, таких как отсутствие потоковобезопасных классов и методов, отсутствие логики часовых поясов и общий дизайн API, который было непросто понять.
Руководствуясь этими проблемами, автор
Joda-Time (популярный заменитель
тусклого API до Java 8) и Oracle представили нам новый API даты /
времени через java.time
.
LocalDate
является одним из наиболее часто используемых классов
java.time
наряду с LocalTime
и LocalDateTime
. Он представляет
дату без полей времени или часового пояса с форматом даты по умолчанию
yyyy-mm-dd
.
Встроенные методы сравнения очень похожи на класс Date
LocalDate.isAfter()
LocalDate.isBefore()
LocalDate.isEqual()
LocalDate.compareTo()
LocalDate.equals()
Использование LocalDate.isAfter () , LocalDate.isBefore () и LocalDate.isEqual ()
Все три метода проверяют, находится ли вызванный LocalDate
до, после
или равный аргументу, возвращая boolean
значения соответственно.
LocalDate
два экземпляра LocalDate, используя вспомогательный метод
of()
и передав значения year
, month
и day
:
LocalDate date1 = LocalDate.of(2020, 3, 25);
LocalDate date2 = LocalDate.of(2020, 7, 29);
if (date1.isAfter(date2))
System.out.println(String.format("%s comes after %s", date1, date2));
else if (date1.isBefore(date2))
System.out.println(String.format("%s comes before %s", date1, date2));
else if (date1.isEqual(date2))
System.out.println("Both dates are equal");
Это приводит к:
2020-03-25 comes before 2020-07-29
Использование LocalDate.compareTo () и LocalDate.equals ()
Опять же, как обычно, compareTo()
сравнивает экземпляры и возвращает
-1
, 0
или 1
зависимости от значений LocalDate
s. С другой
стороны, метод equals()
проверяет, указывают ли ссылки на один и тот
же объект в памяти:
LocalDate date1 = LocalDate.of(2021, 12, 12);
LocalDate date2 = LocalDate.of(2021, 12, 12);
if(date1.equals(date2)) {
System.out.println("Same LocalDate");
} else if(date1.compareTo(date2) > 0) {
System.out.println(String.format("%s is after %s", date1, date2));
} else if(date1.compareTo(date2) < 0) {
System.out.println(String.format("%s is before %s", date1, date2));
} else {
System.out.println(String.format("%s and %s represent the same date", date1, date2));
}
Поскольку мы создали два LocalDate
с одинаковыми значениями, без
использования ключевого слова new
new Object
, это один и тот же
LocalDate
:
Same LocalDate
Фактически, поскольку LocalDate
не имеет общедоступного конструктора
, мы не можем вызывать для него new
.
Сравнение календарей
Класс java.util.Calendar
является частью старого API даты и времени и
в основном используется для преобразования между моментами и полями
календаря, такими как DAY_OF_MONTH
и т. Д.
Они также могут содержать данные, связанные с датой, и, конечно же, их можно сравнивать:
Calendar c1 = Calendar.getInstance();
c1.set(2020, Calendar.AUGUST, 15);
Calendar c2 = Calendar.getInstance();
c2.set(2020, Calendar.JULY, 4);
if(c1.equals(c2))
System.out.println("Calendars are equal");
else if(c1.after(c2))
System.out.println(c1.getTime() + " comes after " + c1.getTime());
else if(c1.before(c2))
System.out.println(c1.getTime() + " comes before " + c2.getTime());
Это приводит к:
Sat Aug 15 14:22:24 UTC 2020 comes after Sat Aug 15 14:22:24 UTC 2020
Сравнение с Joda-Time
Joda-Time была стандартизированной сторонней библиотекой даты /
времени для Java до Java 8. Она решала проблемы, присутствующие в
исходном API, которых было много. Это также послужило вдохновением и
отправной точкой для капитального ремонта всего API, в результате чего
появился текущий пакет java.time
С Joda-Time мы можем использовать до восьми различных календарных систем, управлять часовыми поясами или даже определять свои собственные календари. Но что еще более важно, нам не нужно беспокоиться об изменчивости .
Вместо того, чтобы представлять даты как экземпляры во времени,
Joda-Time представляет их как фактические даты. Для того, чтобы показать
, как мы сравним даты , используя Joda-Time, мы будем использовать
LocalDate
класс (класс Joda-Time) , который является потокобезопасным.
Использование DateTimeComparator
Класс DateTimeComparator
специально создан для сравнения дат. Он
работает с ReadableInstant
s, String
s, Date
s, Calendar
s и
Long
s. Итак, нам нужно преобразовать наши Joda-Time LocalDate
s в
Date
s:
LocalDate date1 = new LocalDate(2021, 11, 11);
LocalDate date2 = new LocalDate(2021, 12, 12);
int result = DateTimeComparator.getInstance()
.compare(date1.toDate(), date2.toDate());
System.out.println(result);
Этот метод возвращает целочисленный результат, как и метод compareTo()
, где -1
означает, что первая дата предшествует второй, 0
означает, что они такие же, а 1
означает, что первый объект находится
после второго:
-1
Использование LocalDate.isEqual ()
Аналогично текущему API даты / времени мы можем использовать isEqual()
:
LocalDate date1 = new LocalDate(2021, 11, 11);
LocalDate date2 = new LocalDate(2021, 12, 12);
System.out.println(date1.isEqual(date2));
В результате получается boolean
:
false
Использование LocalDate.isBefore () и LocalDate.isAfter ()
Опять же, как и в случае с API Java 8, мы можем использовать
isBefore()
и isAfter()
для сравнения двух LocalDate
:
LocalDate date1 = new LocalDate(2021, 11, 11);
LocalDate date2 = new LocalDate(2021, 12, 12);
System.out.println(date1.isBefore(date2));
System.out.println(date1.isAfter(date2));
Это приводит к:
true
false
Использование LocalDate.compareTo ()
Расширение Comparable
, то LocalDate
класс имеет compareTo()
метод, который возвращает целое число больше, меньше или равное нулю.
Поля сравниваются с тем и первым полем , который не является
равным используются для определения результата:
LocalDate today = LocalDate.now();
LocalDate tomorrow = new LocalDate(today.getYear(),
today.getMonthOfYear(),
today.getDayOfMonth() + 1);
int result = today.compareTo(tomorrow);
if(result == 0)
System.out.println("Dates are equal");
else if (result < 0)
System.out.println(today + " is before " + tomorrow);
else
System.out.println(today + " is after " + tomorrow);
Это приводит к:
2021-04-14 is before 2021-04-15
Использование LocalDate.equals ()
И, наконец, метод equals()
проверяет равенство ссылок на объект:
LocalDate date1 = new LocalDate(2021, 3, 25);
LocalDate date2 = new LocalDate(2021, 2, 25);
System.out.println(date1.equals(date2));
Это приводит к:
false
Заключение
В этой статье мы рассмотрели несколько способов сравнения дат в Java. Мы
использовали устаревший java.util.Date
для старых проектов и класс
java.util.Calendar
Затем мы перешли к более современному API даты и времени Java 8 и, наконец, к Joda-Time.