Comparing Date objects


Calendar, Date, and LocalDate

Version < Java SE 8

before, after, compareTo and equals methods

//Use of Calendar and Date objects 
final Date currentDate = new Date();
final Calendar myCalendar = Calendar.getInstance();
myCalendar.set(2000, Calendar.DECEMBER, 25, 0, 0, 0);
Date christmasDate = myCalendar.getTime();
 
final Calendar anotherCalendar = Calendar.getInstance();
anotherCalendar.set(2000, Calendar.DECEMBER, 25, 0, 0, 0);
Date sameChristmasDate = anotherCalendar.getTime();
 
// Before example
System.out.printf("Is %1$tF before %2$tF? %3$b%n", currentDate, christmasDate, Boolean.valueOf(currentDate.before(christmasDate)));
System.out.printf("Is %1$tF before %1$tF? %3$b%n", currentDate, currentDate, Boolean.valueOf(currentDate.before(currentDate)));
System.out.printf("Is %2$tF before %1$tF? %3$b%n", currentDate, christmasDate, Boolean.valueOf(christmasDate.before(currentDate)));
 
// After example
System.out.printf("Is %1$tF after %2$tF? %3$b%n", currentDate, christmasDate, Boolean.valueOf(currentDate.after(christmasDate)));
System.out.printf("Is %1$tF after %1$tF? %3$b%n", currentDate, christmasDate, Boolean.valueOf(currentDate.after(currentDate)));
System.out.printf("Is %2$tF after %1$tF? %3$b%n", currentDate, christmasDate, Boolean.valueOf(christmasDate.after(currentDate)));
 
// Compare example
System.out.printf("Compare %1$tF to %2$tF: %3$d%n", currentDate, christmasDate, Integer.valueOf(currentDate.compareTo(christmasDate)));
System.out.printf("Compare %1$tF to %1$tF: %3$d%n", currentDate, christmasDate, Integer.valueOf(currentDate.compareTo(currentDate)));
System.out.printf("Compare %2$tF to %1$tF: %3$d%n", currentDate, christmasDate, Integer.valueOf(christmasDate.compareTo(currentDate)));
 
// Equal example
System.out.printf("Is %1$tF equal to %2$tF? %3$b%n", currentDate, christmasDate, Boolean.valueOf(currentDate.equals(christmasDate)));
System.out.printf("Is %1$tF equal to %2$tF? %3$b%n", christmasDate, sameChristmasDate,
  Boolean.valueOf(christmasDate.equals(sameChristmasDate)));
System.out.printf("Because christmasDate.getTime() -> %1$d is different from sameChristmasDate.getTime() -> %2$d, 
there are milliseconds!%n",  Long.valueOf(christmasDate.getTime()), Long.valueOf(sameChristmasDate.getTime()));
 
// Clear milliseconds from calendars
myCalendar.clear(Calendar.MILLISECOND);
anotherCalendar.clear(Calendar.MILLISECOND);
christmasDate = myCalendar.getTime();
sameChristmasDate = anotherCalendar.getTime();
System.out.printf("Is %1$tF equal to %2$tF after clearing ms? %3$b%n", christmasDate,
 sameChristmasDate,  Boolean.valueOf(christmasDate.equals(sameChristmasDate)));

isBefore, isAfter, compareTo and equals methods

final LocalDate currentDate = LocalDate.now();
final LocalDate anniversaryDate = LocalDate.of(2023, 7, 15);
final LocalDate sameAnniversaryDate = LocalDate.of(2023, 7, 15);
 
// isBefore example
System.out.printf("Is %1$tF before %2$tF? %3$b%n", currentDate, anniversaryDate, Boolean.valueOf(currentDate.isBefore(anniversaryDate)));
System.out.printf("Is %1$tF before %1$tF? %3$b%n", currentDate, anniversaryDate, Boolean.valueOf(currentDate.isBefore(currentDate)));
System.out.printf("Is %2$tF before %1$tF? %3$b%n", currentDate, anniversaryDate, Boolean.valueOf(anniversaryDate.isBefore(currentDate)));
 
// isAfter example
System.out.printf("Is %1$tF after %2$tF? %3$b%n", currentDate, anniversaryDate, Boolean.valueOf(currentDate.isAfter(anniversaryDate)));
System.out.printf("Is %1$tF after %1$tF? %3$b%n", currentDate, anniversaryDate, Boolean.valueOf(currentDate.isAfter(currentDate)));
System.out.printf("Is %2$tF after %1$tF? %3$b%n", currentDate, anniversaryDate, Boolean.valueOf(anniversaryDate.isAfter(currentDate)));
 
// compareTo example
System.out.printf("Compare %1$tF to %2$tF %3$d%n", currentDate, anniversaryDate, Integer.valueOf(currentDate.compareTo(anniversaryDate)));
System.out.printf("Compare %1$tF to %1$tF %3$d%n", currentDate, anniversaryDate, Integer.valueOf(currentDate.compareTo(currentDate)));
System.out.printf("Compare %2$tF to %1$tF %3$d%n", currentDate, anniversaryDate, Integer.valueOf(anniversaryDate.compareTo(currentDate)));
 
// equals example
System.out.printf("Is %1$tF equal to %2$tF? %3$b%n", currentDate, anniversaryDate, Boolean.valueOf(currentDate.equals(anniversaryDate)));
System.out.printf("Is %1$tF to %2$tF? %3$b%n", anniversaryDate, sameAnniversaryDate, Boolean.valueOf(anniversaryDate.
equals(sameAnniversaryDate)));
 
// isEqual example
System.out.printf("Is %1$tF equal to %2$tF? %3$b%n", currentDate, anniversaryDate, Boolean.valueOf(currentDate.isEqual(anniversaryDate)));
System.out.printf("Is %1$tF to %2$tF? %3$b%n", anniversaryDate, sameAnniversaryDate, Boolean.valueOf(anniversaryDate.
isEqual(sameAnniversaryDate)));
 

Date comparison before Java 8

Before Java 8, dates could be compared using java.util.Calendar and java.util.Date classes. Date class offers 4 methods to compare dates :

compareTo method returns positive integer.

  • Value greater than 0 : when the Date is after the Date argument
  • Value greater than 0 : when the Date is before the Date argument
  • Value equals to 0 : when the Date is equal to the Date argument

equals results can be surprising as shown in the example because values, like milliseconds, are not initialize with the same value if not explicitly given.

Since Java 8

With Java 8 a new Object to work with Date is available java.time.LocalDate. LocalDate implements ChronoLocalDate, the abstract representation of a date where the Chronology, or calendar system, is pluggable.

To have the date time precision the Object java.time.LocalDateTime has to be used. LocalDate and LocalDateTime use the same methods name for comparing.

Comparing dates using a LocalDate is different from using ChronoLocalDate because the chronology, or calendar system are not taken in account the first one.

Because most application should use LocalDate, ChronoLocalDate is not included in examples. Further reading here

  • Most applications should declare method signatures, fields and variables as LocalDate, not this[ChronoLocalDate] interface.

LocalDate has 5 methods to compare dates :

  • isAfter(ChronoLocalDate other)
  • isBefore(ChronoLocalDate other)
  • isEqual(ChronoLocalDate other)
  • compareTo(ChronoLocalDate other)
  • equals(Object obj)

In case of LocalDate parameter, isAfter, isBefore, isEqual, equals and compareTo now use this method:

int compareTo0(LocalDate otherDate)
{
	int cmp = (year - otherDate.year);
	if (cmp == 0)
	{
		cmp = (month - otherDate.month);
		if (cmp == 0)
		{
			cmp = (day - otherDate.day);
		}
	}
	return cmp;
}

equals method check if the parameter reference equals the date first whereas isEqual directly calls compareTo0.

In case of an other class instance of ChronoLocalDate the dates are compared using the Epoch Day. The Epoch Day count is a simple incrementing count of days where day 0 is 1970-01-01 (ISO).

Basic Programs