Wednesday, June 07, 2006

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/

8 Comments:

Anonymous Anonymous said...

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

11 September, 2006 18:47  
Blogger Michael Vorburger said...

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

11 September, 2006 20:15  
Blogger tony said...

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

10 March, 2008 16:38  
Anonymous Anonymous said...

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. :)

20 May, 2008 15:34  
Anonymous Anonymous said...

mp3 mp4 player
wow gold kaufen
portabel mp3 player
mp3
gold wow
mp4
mp3 player
wow gold kauf
wow gold
lotro gold
lotro gold
wow goud
hdro gold
Ever quest platinum
wow powerleveling
lineage 2 adena
runescape money
buy world of warcraft gold
mp3 player kaufen
wow gold cheap
guild wars gold
world of warcraft
buy cheap wow gold
gold wow

23 May, 2008 04:52  
Anonymous Anonymous said...

cheap wow gold
mp3 player
mp4 player
sell wow gold
cheap mp3 players
mp3 player
wow gold
zubehoer mp3 player
best mp3 player
eve isk
mp4 players
mp3 mp4 player
buy eve isk
1BG MP3 PLAYER
2BG MP3 PLAYER
baladeur MP3
baladeurs MP3
cheapest wow gold
mp3 player
mp4 player
guild wars gold
wow powerleveling guide
world of warcraft gold
cheap world of warcraft gold

23 May, 2008 04:52  
Anonymous Anonymous said...

wow gold
lord of the rings online gold
world of warcraft gold
lotro gold
eve isk
buy wow gold
eq2 platinum
mp3 players
po wow
wow gold
lotro gold
wow gold
wow goud
hdro gold
Ever quest platinum
wow powerleveling
lineage 2 adena
runescape money
lecteur mp3
lecteurs mp3
guild wars gold
wow gold guide
wow power leveling
wow powerleveling

23 May, 2008 05:00  
Anonymous Anonymous said...

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

27 May, 2008 20:36  

Post a Comment

Links to this post:

Create a Link

<< Home