### Number of days between two dates? (Java)

Recently a needed to get the number of days between two dates in Java.

Easy, right? Quite a few pages & articles suggest, and I admit my first iteration too, was:

Calendar firstDay = new GregorianCalendar(2006, Calendar.FEBRUARY, 3)

Calendar lastDay = new GregorianCalendar(2006, Calendar.JULY, 17);

static final long DAY_MS = 1000 * 60 * 60 * 24;

int days = (lastDay.getTime().getTime() - firstDay.getTime().getTime()) / DAY_MS;

It turns out this is WRONG, for example for the two dates given (days == 163, but shold be 164!) - some rounding error. This will round correctly, as some better Web pages explain:

double daysDouble = lastLong - firstLong;

int days = (int) Math.round(daysDouble / DAY_MS); // = 164

but using the Calendar API provides a clearer, more reable and most importantly correct version, too:

assert firstDay.get(Calendar.YEAR) == lastDay.get(Calendar.YEAR); // Assumption

int days = lastDay.get(Calendar.DAY_OF_YEAR) - firstDay.get(Calendar.DAY_OF_YEAR);

Or, for more calculations of this kind, consider http://joda-time.sourceforge.net/

Easy, right? Quite a few pages & articles suggest, and I admit my first iteration too, was:

Calendar firstDay = new GregorianCalendar(2006, Calendar.FEBRUARY, 3)

Calendar lastDay = new GregorianCalendar(2006, Calendar.JULY, 17);

static final long DAY_MS = 1000 * 60 * 60 * 24;

int days = (lastDay.getTime().getTime() - firstDay.getTime().getTime()) / DAY_MS;

It turns out this is WRONG, for example for the two dates given (days == 163, but shold be 164!) - some rounding error. This will round correctly, as some better Web pages explain:

double daysDouble = lastLong - firstLong;

int days = (int) Math.round(daysDouble / DAY_MS); // = 164

but using the Calendar API provides a clearer, more reable and most importantly correct version, too:

assert firstDay.get(Calendar.YEAR) == lastDay.get(Calendar.YEAR); // Assumption

int days = lastDay.get(Calendar.DAY_OF_YEAR) - firstDay.get(Calendar.DAY_OF_YEAR);

Or, for more calculations of this kind, consider http://joda-time.sourceforge.net/

## 5 Comments:

I don't think this will work if the dates are in different years.

Absolutely, you are right; that's why I'd put that assert with // assumption in the code snippet above.

I have run into the same problem. My date ran is one hour less than expected. My date range like your spanned the start of daylight savings. I think that is the problem. You can't assume a constant MS/Day. The first day of daylight savings has only 23 hours.

Tony

What about this:

static final long ONE_HOUR = 60 * 60 * 1000L;

public long daysBetween(Date startDate, Date endDate) {

return ((endDate.getTime() - startDate.getTime() + ONE_HOUR) / (ONE_HOUR * 24));

}

or another one a bit different but same meaning:

private static final long MILISECONDS_PER_DAY = 24 * 60 * 60 * 1000;

public int getDaysBetweenDates(Date startDate, Date endDate) {

long diff = endDate.getTime() - startDate.getTime();

int days = (int) Math.floor(diff / MILISECONDS_PER_DAY);

return Math.abs(days);

}

David N. :)

here's a rather brutal way to do this :)

public static int getDays(Calendar from, Calendar to)

{

int cnt = 0;

while (from.before(to)) {

cnt++;

if (from.getActualMaximum(DATE) == from.get(DATE)) {

from.roll(MONTH, true);

}

if (from.getActualMaximum(MONTH) == from.get(MONTH)) {

from.roll(YEAR, true);

}

from.roll(DATE, true);

}

return ctn;

}

Post a Comment

<< Home