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

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

Пример:

date1 - 22-02-2010
date2 - 07-04-2010 сегодня
date3 - 25-12-2010

date3 всегда больше date1, а date2 всегда сегодня. Как мне проверить, находится ли сегодняшняя дата между date1 и date 3?


person ant    schedule 07.04.2010    source источник


Ответы (11)


Date имеет до и после методов и может быть по сравнению друг с другом следующим образом:

if(todayDate.after(historyDate) && todayDate.before(futureDate)) {
    // In between
}

Для исчерпывающего сравнения:

if(!historyDate.after(todayDate) && !futureDate.before(todayDate)) {
    /* historyDate <= todayDate <= futureDate */ 
}

Вы также можете попробовать Joda-Time, но учтите, что:

Joda-Time - это де-факто стандартная библиотека даты и времени для Java до Java SE 8. Теперь пользователям предлагается перейти на java.time (JSR-310).

Бэк-порты доступны для Java 6 и 7, а также для Android.

person Bart Kiers    schedule 07.04.2010
comment
Это все включено или эксклюзивно для границ? - person Daniel Hári; 03.12.2015
comment
@ DanielHári нет, это не включено. вы можете использовать решение, предложенное в первом комментарии, или использовать CompareTo () ›= 0. - person Mifmif; 10.05.2016
comment
Нормальный, обычно левый, включающий, правый, исключающий, поэтому я думаю, что это должно быть указано точно. С левой включающей, правой исключительной границами вы можете легко указать например: интервал в месяц: [2016/04/01, 2016/05/01], поэтому это нормально и используется по умолчанию во многих случаях использования. - person Daniel Hári; 10.05.2016
comment
К вашему сведению, неприятные старые классы даты и времени, такие как java.util.Date теперь являются устаревшими и заменены классы java.time, встроенные в Java 8 и Java 9. См. Руководство от Oracle. - person Basil Bourque; 23.02.2018
comment
@BasilBourque да, правильно, отсюда и замечания о Joda и java.time для Java 8, которая теперь является стандартной версией (вопреки тому времени, когда я писал этот ответ). Не стесняйтесь редактировать этот ответ и, конечно же, добавлять более свежий пример кода! ;) (РЕДАКТИРОВАТЬ: а, я вижу, вы сами уже дали ответ с указанными примерами) - person Bart Kiers; 23.02.2018


Ниже приведены наиболее распространенные способы сравнения dates (я предпочитаю подход 1):

Подход 1. Использование Date.before(), Date.after() и Date.equals()

if (date1.after(date2)) {
    System.out.println("Date1 is after Date2");
}

if (date1.before(date2)) {
    System.out.println("Date1 is before Date2");
}

if (date1.equals(date2)) {
    System.out.println("Date1 is equal Date2");
}

Подход 2: Date.compareTo()

if (date1.compareTo(date2) > 0) {
    System.out.println("Date1 is after Date2");
} else if (date1.compareTo(date2) < 0) {
    System.out.println("Date1 is before Date2");
} else {
    System.out.println("Date1 is equal to Date2");
}

Подход 3: Calender.before(), Calender.after() и Calender.equals()

Calendar cal1 = Calendar.getInstance();
Calendar cal2 = Calendar.getInstance();
cal1.setTime(date1);
cal2.setTime(date2);

if (cal1.after(cal2)) {
    System.out.println("Date1 is after Date2");
}

if (cal1.before(cal2)) {
    System.out.println("Date1 is before Date2");
}

if (cal1.equals(cal2)) {
    System.out.println("Date1 is equal Date2");
}
person Sunil Kumar Sahoo    schedule 13.01.2014
comment
К вашему сведению, неприятные старые классы даты и времени, такие как java.util.Date , java.util.Calendar и java.text.SimpleDateFormat теперь являются устаревшими, замененными java.time классы, встроенные в Java 8 и Java 9. См. Учебное пособие от Oracle. - person Basil Bourque; 23.02.2018

tl;dr

LocalDate today = LocalDate.now( ZoneId.of( "America/Montreal" ) ) ;
Boolean isBetween = 
    ( ! today.isBefore( localDate1 ) )  // “not-before” is short for “is-equal-to or later-than”.
    &&
    today.isBefore( localDate3 ) ; 

Или, лучше, если вы добавите в свой проект библиотеку ThreeTen-Extra.

LocalDateRange.of(
    LocalDate.of( … ) ,
    LocalDate.of( … )
).contains(
    LocalDate.now()
)

Полуоткрытый подход, где начало - включающее, а окончание - исключающее.

Плохой выбор формата

Кстати, это плохой выбор формата для текстового представления даты или значения даты и времени. По возможности придерживайтесь стандартных форматов ISO 8601. Форматы ISO 8601 однозначны, понятны для всех людей и легко анализируются машиной.

Для значения только даты стандартный формат - ГГГГ-ММ-ДД. Обратите внимание на преимущество этого формата в том, что он является хронологическим при сортировке по алфавиту.

LocalDate

Класс LocalDate представляет значение только даты без времени суток и без часового пояса.

Часовой пояс имеет решающее значение при определении даты. В любой момент дата меняется в зависимости от зоны земного шара. Например, несколько минут после полуночи в Париже, Франция - это новый день, а «вчера ”В Montréal Québec.

ZoneId z = ZoneId.of( "America/Montreal" );
LocalDate today = LocalDate.now( z );

Таблица всех типов даты и времени в Java, как современных, так и устаревших

DateTimeFormatter

Поскольку ваши входные строки имеют нестандартный формат, мы должны определить шаблон форматирования для соответствия.

DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd-MM-uuuu" );

Используйте это для анализа входных строк.

LocalDate start = LocalDate.parse( "22-02-2010" , f );
LocalDate stop = LocalDate.parse( "25-12-2010" , f );

При работе с датой и временем обычно лучше всего определять промежуток времени с помощью подхода Half-Open, где начало включающее, а окончание исключающее. Поэтому мы хотим знать, совпадает ли сегодняшний день с началом или позже начала, а также перед остановкой. Более короткий способ сказать «то же самое или позже, чем старт» - «не до старта».

Boolean intervalContainsToday = ( ! today.isBefore( start ) ) && today.isBefore( stop ) ;

См. ответ от gstackoverflow, в котором показан список методов сравнения, которые вы можете вызвать.


О java.time

java.time встроен в Java 8 и новее. Эти классы заменяют неудобные старые устаревшие классы даты и времени, такие как _ 10_, _ 11_, & _ 12_.

Чтобы узнать больше, см. Учебник Oracle . И поищите в Stack Overflow множество примеров и объяснений. Спецификация - JSR 310.

Проект Joda-Time теперь в режим обслуживания, советует перейти на java.time.

Вы можете обмениваться объектами java.time непосредственно с вашей базой данных. Используйте драйвер JDBC, совместимый с JDBC 4.2 или новее. Нет необходимости в строках, нет необходимости в java.sql.* классах. Hibernate 5 и JPA 2.2 поддерживают java.time.

Где взять классы java.time?

Проект ThreeTen-Extra расширяет java.time дополнительными классами. Этот проект является испытательной площадкой для возможных будущих дополнений к java.time. Здесь вы можете найти несколько полезных классов, например _14 _, YearWeek, _ 16_ и подробнее.


ОБНОВЛЕНИЕ: этот раздел «Joda-Time» ниже остался нетронутым как история. Проект Joda-Time теперь в режим обслуживания, советует перейти на java.time классы.

Джода-Тайм

Другие ответы верны в отношении связанных классов java.util.Date и java.util.Calendar. Но эти занятия, как известно, доставляют много хлопот. Итак, вот пример кода с использованием библиотеки Joda-Time 2.3.

Если вам действительно нужна дата без временной части и без часового пояса, используйте _ 17_ в Joda-Time. Этот класс предоставляет методы сравнения, включая compareTo (используется с Java Comparators), isBefore, isAfter и isEqual.

Входы…

String string1 = "22-02-2010";
String string2 = "07-04-2010";
String string3 = "25-12-2010";

Определите средство форматирования, описывающее входные строки…

DateTimeFormatter formatter = DateTimeFormat.forPattern( "dd-MM-yyyy" );

Используйте средство форматирования для синтаксического анализа строк в объекты LocalDate…

LocalDate localDate1 = formatter.parseLocalDate( string1 );
LocalDate localDate2 = formatter.parseLocalDate( string2 );
LocalDate localDate3 = formatter.parseLocalDate( string3 );

boolean is1After2 = localDate1.isAfter( localDate2 );
boolean is2Before3 = localDate2.isBefore( localDate3 );

Выгрузить в консоль…

System.out.println( "Dates: " + localDate1 + " " + localDate2 + " " + localDate3 );
System.out.println( "is1After2 " + is1After2 );
System.out.println( "is2Before3 " + is2Before3 );

При запуске…

Dates: 2010-02-22 2010-04-07 2010-12-25
is1After2 false
is2Before3 true

Так что посмотрите, находится ли второй между двумя другими (исключительно, что означает, что он не равен ни одной конечной точке) ...

boolean is2Between1And3 = ( ( localDate2.isAfter( localDate1 ) ) && ( localDate2.isBefore( localDate3 ) ) );

Работа с промежутками времени

Если вы работаете с промежутками времени, я предлагаю изучить в Joda-Time классы: Продолжительность, Интервал и Period. Такие методы, как overlap и contains, упрощают сравнение.

Для текстовых представлений см. Стандарт ISO 8601:

  • duration
    Формат: PnYnMnDTnHnMnS
    Пример: P3Y6M4DT12H30M5S
    (Означает «Три года, шесть месяцев, четыре дня, двенадцать часов, тридцать минут и пять секунд»)
  • interval
    Формат: начало / конец
    Пример: 2007-03-01T13 : 00: 00Z / 2008-05-11T15: 30: 00Z

Классы Joda-Time могут работать со строками в обоих этих форматах как на входе (синтаксический анализ), так и на выходе (генерация строк).

Joda-Time выполняет сравнения, используя подход Half-Open, где начало диапазона включающее, а окончание исключающее. Этот подход является разумным для работы с промежутками времени. Поищите в StackOverflow дополнительную информацию.

person Basil Bourque    schedule 29.01.2014
comment
Это должно быть вверху всех остальных ответов - person Hemil; 09.02.2020

Сравните две даты:

  Date today = new Date();                   
  Date myDate = new Date(today.getYear(),today.getMonth()-1,today.getDay());
  System.out.println("My Date is"+myDate);    
  System.out.println("Today Date is"+today);
  if (today.compareTo(myDate)<0)
      System.out.println("Today Date is Lesser than my Date");
  else if (today.compareTo(myDate)>0)
      System.out.println("Today Date is Greater than my date"); 
  else
      System.out.println("Both Dates are equal"); 
person sam    schedule 07.04.2010
comment
Я думаю, что new Date (today.getYear (), today.getMonth () - 1, today.getDay ()); это устарело. download.oracle.com/javase/6/docs/ api / java / util / Date.html - person Dr. No; 03.11.2011
comment
@Muath: Хотя я не уверен на 100%, я думаю, это потому, что компонент месяца в Date имеет нулевой индекс. - person Lii; 23.03.2015
comment
я думаю, что там еще часть не работает :) - person Sachith; 24.12.2016

Обновление для Java 8 и новее

Эти методы существуют в LocalDate, _ 6_ и _ 7_ классы.

Эти классы встроены в Java 8 и новее. Большая часть функций java.time перенесена на Java 6 и 7 в ThreeTen-Backport и дополнительно адаптирован к Android в ThreeTenABP (см. Как использовать… ).

person gstackoverflow    schedule 13.11.2015
comment
как скачать эти три класса - person Punithapriya; 08.08.2016
comment
@Punithapriya Эти классы существуют в стандартной библиотеке java 8. Таким образом, просто скачайте java 8 - person gstackoverflow; 08.08.2016
comment
да, я видел спасибо - person Punithapriya; 08.08.2016

Вы можете использовать Date.getTime(), который :

Возвращает количество миллисекунд с 1 января 1970 г., 00:00:00 по Гринвичу, представленное этим объектом Date.

Это означает, что вы можете сравнивать их как числа:

if (date1.getTime() <= date.getTime() && date.getTime() <= date2.getTime()) {
    /*
     * date is between date1 and date2 (both inclusive)
     */
}

/*
 * when date1 = 2015-01-01 and date2 = 2015-01-10 then
 * returns true for:
 * 2015-01-01
 * 2015-01-01 00:00:01
 * 2015-01-02
 * 2015-01-10
 * returns false for:
 * 2014-12-31 23:59:59
 * 2015-01-10 00:00:01
 * 
 * if one or both dates are exclusive then change <= to <
 */
person Salman A    schedule 14.05.2015

Попробуй это

public static boolean compareDates(String psDate1, String psDate2) throws ParseException{
        SimpleDateFormat dateFormat = new SimpleDateFormat ("dd/MM/yyyy");
        Date date1 = dateFormat.parse(psDate1);
        Date date2 = dateFormat.parse(psDate2);
        if(date2.after(date1)) {
            return true;
        } else {
            return false;
        }
    }
person Garambe    schedule 24.11.2015

Используйте getTime (), чтобы получить числовое значение даты, а затем сравните, используя возвращенные значения.

person Everyone    schedule 07.04.2010

Этот код, определяющий, что сегодня, находится в некотором сроке .. на основе региональных настроек КОРЕИ

    Calendar cstart = Calendar.getInstance(Locale.KOREA);
    cstart.clear();
    cstart.set(startyear, startmonth, startday);


    Calendar cend = Calendar.getInstance(Locale.KOREA);
    cend.clear();
    cend.set(endyear, endmonth, endday);

    Calendar c = Calendar.getInstance(Locale.KOREA);

    if(c.after(cstart) && c.before(cend)) {
        // today is in startyear/startmonth/startday ~ endyear/endmonth/endday
    }
person Brownsoo Han    schedule 27.11.2013

Этот метод сработал для меня:

 public static String daysBetween(String day1, String day2) {
    String daysBetween = "";
    SimpleDateFormat myFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    try {
        Date date1 = myFormat.parse(day1);
        Date date2 = myFormat.parse(day2);
        long diff = date2.getTime() - date1.getTime();
        daysBetween = ""+(TimeUnit.DAYS.convert(diff, TimeUnit.MILLISECONDS));
    } catch (ParseException e) {
        e.printStackTrace();
    }
    return daysBetween;
}
person Iman Marashi    schedule 06.01.2017
comment
Не отвечает на вопрос. Вопрос включает три свидания, а не две. «Как мне проверить, находится ли сегодняшняя дата между date1 и date 3?» Кроме того, этот расчет возвращает количество 24-часовых периодов, а не количество прошедших календарных дней. Еще одна проблема: в этом ответе используются значения даты и времени, в то время как вопрос касается значений только даты без времени суток. - person Basil Bourque; 07.01.2017