Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calculating the difference between two Java date instances

I'm using Java's java.util.Date class in Scala and want to compare a Date object and the current time. I know I can calculate the delta by using getTime():

(new java.util.Date()).getTime() - oldDate.getTime() 

However, this just leaves me with a long representing milliseconds. Is there any simpler, nicer way to get a time delta?

like image 581
pr1001 Avatar asked Oct 12 '09 15:10

pr1001


People also ask

How do you find the difference between two date objects?

Calculate the no. of days between two dates, divide the time difference of both the dates by no. of milliseconds in a day (1000*60*60*24) Print the final result using document.

How can you find out the difference between two dates in Java 8?

Using JodaTime, you can get the difference between two dates in Java using the following code: Days d = Days. daysBetween(startDate, endDate). getDays();


1 Answers

Simple diff (without lib)

/**  * Get a diff between two dates  * @param date1 the oldest date  * @param date2 the newest date  * @param timeUnit the unit in which you want the diff  * @return the diff value, in the provided unit  */ public static long getDateDiff(Date date1, Date date2, TimeUnit timeUnit) {     long diffInMillies = date2.getTime() - date1.getTime();     return timeUnit.convert(diffInMillies,TimeUnit.MILLISECONDS); } 

And then can you call:

getDateDiff(date1,date2,TimeUnit.MINUTES); 

to get the diff of the 2 dates in minutes unit.

TimeUnit is java.util.concurrent.TimeUnit, a standard Java enum going from nanos to days.


Human readable diff (without lib)

public static Map<TimeUnit,Long> computeDiff(Date date1, Date date2) {      long diffInMillies = date2.getTime() - date1.getTime();      //create the list     List<TimeUnit> units = new ArrayList<TimeUnit>(EnumSet.allOf(TimeUnit.class));     Collections.reverse(units);      //create the result map of TimeUnit and difference     Map<TimeUnit,Long> result = new LinkedHashMap<TimeUnit,Long>();     long milliesRest = diffInMillies;      for ( TimeUnit unit : units ) {          //calculate difference in millisecond          long diff = unit.convert(milliesRest,TimeUnit.MILLISECONDS);         long diffInMilliesForUnit = unit.toMillis(diff);         milliesRest = milliesRest - diffInMilliesForUnit;          //put the result in the map         result.put(unit,diff);     }      return result; } 

http://ideone.com/5dXeu6

The output is something like Map:{DAYS=1, HOURS=3, MINUTES=46, SECONDS=40, MILLISECONDS=0, MICROSECONDS=0, NANOSECONDS=0}, with the units ordered.

You just have to convert that map to an user-friendly string.


Warning

The above code snippets compute a simple diff between 2 instants. It can cause problems during a daylight saving switch, like explained in this post. This means if you compute the diff between dates with no time you may have a missing day/hour.

In my opinion the date diff is kind of subjective, especially on days. You may:

  • count the number of 24h elapsed time: day+1 - day = 1 day = 24h

  • count the number of elapsed time, taking care of daylight savings: day+1 - day = 1 = 24h (but using midnight time and daylight savings it could be 0 day and 23h)

  • count the number of day switches, which means day+1 1pm - day 11am = 1 day, even if the elapsed time is just 2h (or 1h if there is a daylight saving :p)

My answer is valid if your definition of date diff on days match the 1st case

With JodaTime

If you are using JodaTime you can get the diff for 2 instants (millies backed ReadableInstant) dates with:

Interval interval = new Interval(oldInstant, new Instant()); 

But you can also get the diff for Local dates/times:

// returns 4 because of the leap year of 366 days new Period(LocalDate.now(), LocalDate.now().plusDays(365*5), PeriodType.years()).getYears()   // this time it returns 5 new Period(LocalDate.now(), LocalDate.now().plusDays(365*5+1), PeriodType.years()).getYears()   // And you can also use these static methods Years.yearsBetween(LocalDate.now(), LocalDate.now().plusDays(365*5)).getYears() 
like image 91
Sebastien Lorber Avatar answered Sep 28 '22 18:09

Sebastien Lorber