Как сравнивать даты на Java

Введение Даты - это то, с чем мы сталкиваемся в повседневной жизни, независимо от того, используются ли они для календарей, планирования встреч или даже для запоминания дней рождения. Естественно, при работе с датами нам часто нужно знать, наступает ли определенная дата до или после другой, или они представляют одну и ту же календарную дату. В этой статье мы рассмотрим, как сравнить две даты в Java. * Сравнение дат * Использование Date.compareTo () * Использование Date.before (), Date.after () и Date.equals () *

Вступление

Даты - это то, с чем мы сталкиваемся в повседневной жизни, независимо от того, используются ли они для календарей, планирования встреч или даже для запоминания дней рождения. Естественно, при работе с датами нам часто нужно знать, наступает ли определенная дата до или после другой, или они представляют одну и ту же календарную дату.

В этой статье мы рассмотрим, как сравнить две даты в 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.

comments powered by Disqus