If I wanted to compare only the date parts of the day, ignoring the time parts, it should be simple, right?

If I have two date instances representing “23 Oct 2008 22:41” and “23 Oct 2008 14:22”, and I want to determine that they represent the same day, there should be some method in the JDK to help me, so I thought. But its surprisingly complicated – just not there!

The java Date object is only a wrapper around a long thats the number of milliseconds since the standard base time known as “the epoch“, namely January 1, 1970, 00:00:00 GMT. So it dosen’t really have any day part. The closest we can do is call setHour, setMinute and setSecond to 0 for both the dates in comparison, but this is laborious and also those methods are deprecated.

The Calendar class, which might appear to be better as it has replacements for the deprecated Date methods, still doesn’t offer any seperation of date and time. Even here, one approach to compare would involve zeroing out the hour, minute and second.

Maybe one way to do this would be:

Calendar today = Calendar.getInstance();

today.set(today.get(Calendar.YEAR),
		  today.get(Calendar.MONTH),
		  today.get(Calendar.DAY_OF_MONTH),
		  0,   // Hour
		  0,   // Minute
		  0);  // Second

Calendar today2 = Calendar.getInstance();

today2.set(today.get(Calendar.YEAR),
		  today.get(Calendar.MONTH),
		  today.get(Calendar.DAY_OF_MONTH),
		  0,   // Hour
		  0,   // Minute
		  0);  // Second

This would be refactored into some static utility method of course. Anyway, I’d have to hope that today.equals(today2) will return true – only hope because even before trying that out, I’m paranoid about whether the milliseconds component still has some value that will result in inequality! Even otherwise, seperate set methods of the Calendar class can be called to set all the irrelevant components to zero, and then the before or after methods can be conveniently used.

The Apache Commons project includes a utility class that offered a single static call, DateUtils.isSameDay that takes two Date or Calendar objects, and compares only the date parts!

I wondered how they did it and dug up the source* …

    public static boolean isSameDay(Date date1, Date date2) {
        if (date1 == null || date2 == null) {
            throw new IllegalArgumentException("The date must not be null");
        }
        Calendar cal1 = Calendar.getInstance();
        cal1.setTime(date1);
        Calendar cal2 = Calendar.getInstance();
        cal2.setTime(date2);
        return isSameDay(cal1, cal2);
    }


 public static boolean isSameDay(Calendar cal1, Calendar cal2) {
        if (cal1 == null || cal2 == null) {
            throw new IllegalArgumentException("The date must not be null");
        }
        return (cal1.get(Calendar.ERA) == cal2.get(Calendar.ERA) &&
                cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR) &&
                cal1.get(Calendar.DAY_OF_YEAR) == cal2.get(Calendar.DAY_OF_YEAR));
    }

Some additional useful methods could be isEarlierDay, isLaterDay, where the == would be substituted by > or < operators.


* source is also easily viewable using JadClipse in conjunction with JAD, but it wouldn’t show the static variable names like Calendar.ERA but just put in the numeric value.