CodeMonkey
CodeMonkey

Reputation: 2295

Fractional Number of Days between DateTime objects in Java

How do I find the fractional difference in Days between two Joda-Time DateTime instances?

Days.daysBetween(start, end).getDays() gives me a round number like 10/15 etc. What i need to get is exact value like 10.15 or 15.78

Upvotes: 3

Views: 1769

Answers (4)

Anonymous
Anonymous

Reputation: 86369

To get a number of days with a fraction, calculate the difference in a small enough unit for your precision requirement, then convert to double before doing the division that converts to days:

    DateTimeZone zone = DateTimeZone.forID("Europe/Copenhagen");
    DateTime date1 = new DateTime(1997, 1, 1, 0, 0, zone);
    DateTime date2 = new DateTime(1997, 3, 29, 12, 0, zone);

    int seconds = Seconds.secondsBetween(date1, date2).getSeconds();
    double days = (double) seconds / (double) TimeUnit.DAYS.toSeconds(1);
    System.out.println("Difference in days is " + days);

This snippet outputs:

Difference in days is 87.5

We need to supply the correct time zone to take transitions to and from summer time (DST) into account. In my example both days are in the standard time part of the year in the EU, so 12 hours translate to 0.5 days. If for date2 I had picked a date in the beginning of April, after summer time has begun, this would not have been the case. For example:

    DateTime date2 = new DateTime(1997, 4, 1, 12, 0, zone);

Difference in days is 90.45833333333333

The code will work with a difference of up to about 68 years since an int only holds this many seconds. If you need a greater span of years, consider using minutes or hours instead of seconds. If you pass two dates that are too far apart, Joda-Time is friendly enough to throw an exception rather than tacitly giving you an incorrect result.

This answer was written on the occasion of this duplicate question, and the example datetimes have been taken from there.

Upvotes: 1

CodeMonkey
CodeMonkey

Reputation: 2295

Thanks for the input from comments, i got it working precisely to the seconds using:

double days = Seconds.secondsBetween(start, end).getSeconds()/86400;

Upvotes: 0

Kiran Indukuri
Kiran Indukuri

Reputation: 412

You might miss minutes due to the round off, if you use Hours.hoursBetween .

Try this : (end.getMillis - start.getMillis() )/(1000*3600*24)

Upvotes: 1

Andreas
Andreas

Reputation: 159175

Subtract the time in millis and divide by number of millis per day:

double diff = (end.getMillis() - start.getMillis()) / 86400000d;

Test

DateTime start = new DateTime(2015, 1, 1,  0,  0,  0,   0); // Jan 1, 2015
DateTime end   = new DateTime(2015, 7, 4, 14, 23, 55, 876); // Jul 4, 2015 at 2:23:55.876 PM

final int MILLIS_PER_DAY = 24 * 60 * 60 * 1000; // 86_400_000
double diff = (double)(end.getMillis() - start.getMillis()) / MILLIS_PER_DAY;
System.out.println(diff);

int days = (int)diff;
diff = (diff - days) * 24;
int hours = (int)diff;
diff = (diff - hours) * 60;
int minutes = (int)diff;
diff = (diff - minutes) * 60;
int seconds = (int)diff;
diff = (diff - seconds) * 1000;
int millis = (int)Math.round(diff);
System.out.println(days    + " days, "    +
                   hours   + " hours, "   +
                   minutes + " minutes, " +
                   seconds + " seconds, " +
                   millis  + " millis");

Output

184.55828560185185
184 days, 13 hours, 23 minutes, 55 seconds, 876 millis

Note that it's only 13 hours, not 14, because of daylight savings time.

Upvotes: 0

Related Questions