My name is Veera. I'm a full stack web developer. I have founded http://www.timethetask.com and currently working on my next product. Veera is a DZone MVB and is not an employee of DZone and has posted 33 posts at DZone. You can read more from them at their website. View Full User Profile

Finding the difference between two dates in Java

05.07.2011
| 42955 views |
  • submit to reddit

Let’s say you have two Date objects DateOne and DateTwo. Now you want to find the difference between these two dates and show that in a human readable format; for example “the difference is 2 hours and 30 minutes“. How do you do it in Java?

The obvious answer is, get the milliseconds from these two dates and find the difference. And, then manually convert these milliseconds into hours, minutes, seconds etc.

But, wait a second. There’s an easy way to do this using the TimeUnit class. TimeUnit represents time durations at a given unit of granularity and provides utility methods to convert across units, and to perform timing and delay operations in these units.

Have a look the below code which finds out the difference between two dates and returns them in the form of “h hours and m minutes”.

public String getTimeDiff(Date dateOne, Date dateTwo) {
String diff = "";
long timeDiff = Math.abs(dateOne.getTime() - dateTwo.getTime());
diff = String.format("%d hour(s) %d min(s)", TimeUnit.MILLISECONDS.toHours(timeDiff),
TimeUnit.MILLISECONDS.toMinutes(timeDiff) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(timeDiff)));
return diff;
}

That simple, isn’t it?

From http://veerasundar.com/blog/2011/04/finding-the-difference-between-two-dates-in-java/

Published at DZone with permission of Veera Sundar, author and DZone MVB.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Tags:

Comments

Santhosh Kumar T replied on Sun, 2011/05/08 - 12:46am

DurationUnit from JLibs makes the conversion into human readable format easier

Balázs Bessenyei replied on Sun, 2011/05/08 - 3:34am

What about, if the 2 dates are from different time zones?

Tomasz Nurkiewicz replied on Sun, 2011/05/08 - 4:32am

C'mon! Look at org.apache.commons.lang.time.DurationFormatUtils:

 

DurationFormatUtils.formatDurationHMS(dateTwo.getTime() - dateOne.getTime());

DurationFormatUtils.formatDurationWords(dateTwo.getTime() - dateOne.getTime(), true, true);

 

Will yield:

 

42:08:15.521

1 day 18 hours 8 minutes 15 seconds

 

accordingly. Custom formats are also supported.

Lieven Doclo replied on Sun, 2011/05/08 - 8:41am

How about dropping java.util.Date altogether (worst API ever) and use JodaTime, which has all these features and at least has a decent date/time API?

Geoffrey De Smet replied on Sun, 2011/05/08 - 8:49am

+1 for joda time

 TimeUnit is probably broken in countries that use DST (USA, Europe, ...). Just try that code with March 1th 13:00 and April 30th 13:00. It will end with 23 hours and a day less.

Tero Kadenius replied on Sun, 2011/05/08 - 9:09am in response to: Balázs Bessenyei

Balázs Bessenyei:
If you want the absolute difference between the points in time, this approach works perfectly. The timezone doesn't matter at all since Java Dates don't contain timezone information.

DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z");
Date dateOne = df.parse("2011-02-08 10:00:00 +0300");
Date dateTwo = df.parse("2011-02-08 08:00:00 +0100");
long timeDiff = Math.abs(dateOne.getTime() - dateTwo.getTime());
System.out.println("difference:" + timeDiff); // difference: 0
Ie. the method Veera Sundar describes is a convenient way of comparing dates without the unnecessary hassle with calendar objects.

However, if you want the time difference between the wall clock times, you need Calendar.
TimeZone tz1 = TimeZone.getDefault(); 
tz1.setRawOffset((int)TimeUnit.HOURS.toMillis(3));
Calendar cal1 = new GregorianCalendar(tz1);
cal1.setTime(dateOne);
System.out.println("hours:" + cal1.get(Calendar.HOUR_OF_DAY)); //hours: 10

TimeZone tz2 = TimeZone.getDefault();
tz2.setRawOffset((int)TimeUnit.HOURS.toMillis(1));
Calendar cal2 = new GregorianCalendar(tz2);
cal2.setTime(dateTwo);
System.out.println("hours:" + cal2.get(Calendar.HOUR_OF_DAY)); //hours: 8
Note how the dates are in winter. Dealing with the DST horror is a topic for another discussion. ;)

Balázs Bessenyei replied on Sun, 2011/05/08 - 9:55am in response to: Tero Kadenius

That would have been my point. The original solution can fail in case of TZ and DST needs to be accounted. Like the server and the client are in different time zones and location during a DST transitions. Extremely annoying to deal with it.

Tero Kadenius replied on Sun, 2011/05/08 - 11:32am in response to: Geoffrey De Smet

Geoffrey De Smet:
I definitely agree that Java Date/Time API is often painful to work with. I haven't used Joda time but I've heard good things about it. However, I don't think it's fair to say that TimeUnit is broken. It's a set of convenience methods for converting certain time units to other time units. There is no concept of date in TimeUnit whatsoever. What it does, it does consistently.

The problem with Java standard library is that there is no easy way (that I know of) for comparing time periods (differences between dates).

darryl west replied on Sun, 2011/05/08 - 8:25pm

+1 for joda time. or better yet, jsr-310...

Thomas Mueller replied on Mon, 2011/05/09 - 2:07am

-1 for JSR-310. It is a massively over-engineered API, far too many classes and interfaces, and far too complex. See the Javadocs. Date and time is a relatively simple concept, so the API should be simple as well. I don't know about Joda time, but it seems to be similarly complex.

Lieven Doclo replied on Mon, 2011/05/09 - 2:51am

Thomas, dates and times may be simple aspects, but consider the use of timezones and the problem becomes more complicated. The simplicity of the current java.util.Date API isn't necessarily a good thing. I like to have the difference between a date and a date/time combination. I like to have the difference between a non-localized time and a localized time. And I like the fact that I have classes that express a period of time or an interval. An API needs to cover most basic cases, especially a date API (JSR-310 and JodaTime cover every common case). The one-size-fits-all approach of the current date API is what got us in this mess in the first place.

Philippe Lhoste replied on Mon, 2011/05/09 - 4:31am in response to: Thomas Mueller

"Date and time is a relatively simple concept"

You are joking, right?

Or perhaps you only use them for your locale which hasn't DST, inside a unique time zone, in the 20th century or above...

Thomas Mueller replied on Mon, 2011/05/09 - 5:47am

"Date and time is a relatively simple concept" You are joking, right?

No, I'm not joking. I really don't see a need for 100+ classes / interfaces / exceptions.

I was once working in a project where everything was done in an "object-oriented" way. There was a class FirstName, LastName, Street, City, and so on. This is over-engineering. A first name should be a property, not a class. JSR-310 is similar (I think it did improve a bit in the last years).

Florian Kammermann replied on Mon, 2011/05/09 - 4:01pm

Joda Time saved me in my actual project. Especially the class Interval.Without this class I needed to build it my own and encapsulate all the complexity of Calendar in it.

Just a simple example: try to get the year from a java.util.Date. Yes, you can, but hmmm it's deprecated, what should I do then? Create a Calendar with it and get it over an ugly constant from Calendar, baaad. Or use the Formatter? No I just want do getYear() on wathever I have.

Tero Kadenius replied on Wed, 2011/05/11 - 4:17pm

Inspired by this article I decided to write down my own (random) thoughts about the Java Date/Time API. Ended up being partly a tutorial, partly my bitter opinions about the state of the API. Hopefully it's useful to someone.

http://constarg.wordpress.com/2011/05/11/handling-dates-in-java/

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.