Today I needed to figure out a way to count the number of days passed between two dates and this is the solution I came up with.

Some things in Java seem to be a whole lot trickier than they need be, and working with dates is a good example of this. The Date class’ primary purpose is storing date values. For date oriented calculations the Calendar class should be used. The calendars will handle tricky problems like leap years but the methods for doing this operate at a low level and in many cases you still need to do some of the calculations for yourself. In addition to the standard classes, there’s some great support for working with dates provided in the Apache commons libraries; these libraries don’t provide a method for counting days between two dates though.

Anyway, to cut to the chase, here’s the solution I came up with:

public class DateTools {
    private static final int MILLISECONDS_IN_DAY = 1000 * 60 * 60 * 24;

    /**
     * Calculates the number of days between start and end dates, taking
     * into consideration leap years, year boundaries etc.
     *
     * @param start the start date
     * @param end the end date, must be later than the start date
     * @return the number of days between the start and end dates
     */
    public static long countDaysBetween(Date start, Date end) {
        if (end.before(start)) {
            throw new IllegalArgumentException("The end date must be later than the start date");
        }

        //reset all hours mins and secs to zero on start date
        Calendar startCal = GregorianCalendar.getInstance();
        startCal.setTime(start);
        startCal.set(Calendar.HOUR_OF_DAY, 0);
        startCal.set(Calendar.MINUTE, 0);
        startCal.set(Calendar.SECOND, 0);
        long startTime = startCal.getTimeInMillis();

        //reset all hours mins and secs to zero on end date
        Calendar endCal = GregorianCalendar.getInstance();
        endCal.setTime(end);
        endCal.set(Calendar.HOUR_OF_DAY, 0);
        endCal.set(Calendar.MINUTE, 0);
        endCal.set(Calendar.SECOND, 0);
        long endTime = endCal.getTimeInMillis();

        return (endTime - startTime) / MILLISECONDS_IN_DAY;
    }
}

As you can see each of the dates passed to this method are converted into milliseconds and the number of days between them is calculated based upon the number of days this equates to.

In order to ensure that the times are not relevant in the dates, these are set to zero. This means that if the start date is at 11:00 PM, and the end date is at 1:00 AM the next day, you’ll still get one day returned from this method call, rather than zero.