Вопрос-ответ

How to compare dates in Java? [duplicate]

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

Как мне сравнить промежуточные даты в Java?

Пример:

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

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

Переведено автоматически
Ответ 1

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

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.

Ответ 2

Используйте compareTo:

date1.compareTo(date2);

Ответ 3

Ниже приведен наиболее распространенный способ сравнения 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");
}

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

Approach 3: Calendar.before(), Calendar.after() and Calendar.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");
}
Ответ 4

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

Or, better, if you add the ThreeTen-Extra library to your project.

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

Half-open approach, where beginning is inclusive while ending is exclusive.

Bad Choice of Format

By the way, that is a bad choice of format for a text representation of a date or date-time value. Whenever possible, stick with the standard ISO 8601 formats. ISO 8601 formats are unambiguous, understandable across human cultures, and are easy to parse by machine.

For a date-only value, the standard format is YYYY-MM-DD. Note how this format has the benefit of being chronological when sorted alphabetically.

LocalDate

The LocalDate class represents a date-only value without time-of-day and without time zone.

A time zone is crucial in determining a date. For any given moment, the date varies around the globe by zone. For example, a few minutes after midnight in Paris France is a new day while still “yesterday” in Montréal Québec.

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

Table of all date-time types in Java, both modern and legacy

DateTimeFormatter

As your input strings are non-standard format, we must define a formatting pattern to match.

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

Use that to parse the input strings.

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

In date-time work, usually best to define a span of time by the Half-Open approach where the beginning is inclusive while the ending is exclusive. So we want to know if today is the same or later than the start and also before the stop. A briefer way of saying “is the same or later than the start” is “not before the start”.

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

See the Answer by gstackoverflow showing the list of comparison methods you can call.


About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes. Hibernate 5 & JPA 2.2 support java.time.

Where to obtain the java.time classes?

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.


UPDATE: This “Joda-Time” section below is left intact as history. The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

Joda-Time

Other answers are correct with regard to the bundled java.util.Date and java.util.Calendar classes. But those classes are notoriously troublesome. So here's some example code using the Joda-Time 2.3 library.

If you truly want a date without any time portion and no time zone, then use the LocalDate class in Joda-Time. That class provides methods of comparison including compareTo (used with Java Comparators), isBefore, isAfter, and isEqual.

Inputs…

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

Define a formatter describing the input strings…

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

Use formatter to parse the strings into LocalDate objects…

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

Dump to console…

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

When run…

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

So see if the second is between the other two (exclusively, meaning not equal to either endpoint)…

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

Working With Spans Of Time

If you are working with spans of time, I suggest exploring in Joda-Time the classes: Duration, Interval, and Period. Methods such as overlap and contains make comparisons easy.

For text representations, look at the ISO 8601 standard’s:


  • duration
    Format: PnYnMnDTnHnMnS
    Example: P3Y6M4DT12H30M5S
    (Means “three years, six months, four days, twelve hours, thirty minutes, and five seconds”)

  • интервал
    Формат: начало / конец
    Пример: 2007-03-01T13:00:00Z/2008-05-11T15:30:00Z

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

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

java date