# Where does the extra day come from in duration calculation?

Darya Akbari
Ranch Hand
Posts: 1855
Hi,

I don't know why the heck an extra day is calculated in my following duration calculation . Is there anything wrong in the code below?

The result shows:

That one day is too much .

Any hints?
[ February 07, 2007: Message edited by: Darya Akbari ]

Darya Akbari
Ranch Hand
Posts: 1855
Using the following code produce the same value .

Jim Yingst
Wanderer
Sheriff
Posts: 18671
Yes, the 1 is from January 1, 1970. That's the date you've created. (Though it's very nearly January 2.) If you look at the documentation for the new Date(long) constructor, you will see that that millisecond value is always measured relative to 0:00 GMT Jan 1, 1970. That's the way it's defined. The Date class is simply not designed to deal with differences between two times - the time in millis is always relative to 1970/01/01. While your code will work OK for times less than 24 hours (if you don't try to display the number of days), it doesn't work for larger times.

I recommend you use some simple mathematics to determine the number of days, without using Date for that part. Can you work out how many milliseconds there are in a day? Using that, you should be able to determine how many days are in x milliseconds. If you use similar tricks for hours, minutes, and seconds, you don't really need Date at all. (Though I suppose you can use it if you want, but not for days.)

Ilja Preuss
author
Sheriff
Posts: 14112
Or use http://joda-time.sourceforge.net/ (or wait for JSR 310 to be implemented - http://www.infoq.com/news/2007/02/jsr-310 )

bart zagers
Ranch Hand
Posts: 234
+1 for joda-time

That is such a nice library. Most of the time these date related questions come up (and that is every once and a while), they would be very easy to solve using joda-time.

Darya Akbari
Ranch Hand
Posts: 1855
Originally posted by Jim Yingst:
... you will see that that millisecond value is always measured relative to 0:00 GMT Jan 1, 1970. That's the way it's defined. The Date class is simply not designed to deal with differences between two times - the time in millis is always relative to 1970/01/01.

I recommend you use some simple mathematics to determine the number of days, without using Date for that part. Can you work out how many milliseconds there are in a day? Using that, you should be able to determine how many days are in x milliseconds. If you use similar tricks for hours, minutes, and seconds, you don't really need Date at all. (Though I suppose you can use it if you want, but not for days.)

I thought it was ugly to go through days, hours and minutes calculation. I mean why do we have all these fine Date related classes . One big disadvantage going through above calculations is that you have to format the result yourself which makes it not very reusable for people who prefer different format.

Anyway what do you think of the following code? Look how I get rid of the 1 day :

Also thanks for the joda hint, I will take a look at it.

Regards,
Darya

Ilja Preuss
author
Sheriff
Posts: 14112
Originally posted by Darya Akbari:

I mean why do we have all these fine Date related classes .

Well, one possible answer would be that the classes coming with the JDK actually aren't as fine as they could be...

Jim Yingst
Wanderer
Sheriff
Posts: 18671
[Darya]: I mean why do we have all these fine Date related classes .

For handling harder, less obvious stuff, like how many days are in each month, when are leap years, when does daylight savings time take effect, etc. None of which is needed here, and in fact using Date at all was misleading to at least one programmer (you) and thus requires special explanation (as shown in your comment) to protect maintenance programmers from similar errors.

[Darya]: One big disadvantage going through above calculations is that you have to format the result yourself which makes it not very reusable for people who prefer different format.

What other formats do you think might be necessary? 12-hour clocks to display a duration of 13:00:00 as 01:00:00 PM? You've already hard-coded in the format you're using here anyway. If someone wants to change it, they're going to have to change your code anyway, and understand it well enough to avoid mistakes like using a 12-hour clock. If you want a really flexible international format, you could use a resource bundle to provide formats for various locales I suppose. That would be easier with separate days, hours, minutes, seconds fields I think, rather than the single string you're using.

[Darya]: Anyway what do you think of the following code? Look how I get rid of the 1 day :

Out of curiosity, is there any chance that a duration will ever be greater than 31 days? What would happen then?

I really think simple math is more straightforward than the above solution, and not to be overlooked:

And oh yes, I also recommend Joda time, in general. Though I'm not sure I would bother with it for this particular problem, unless you also have other date/time functionality that you need. (Very possible.) But for this by itself, it's scarcely worth adding a jar file to your program. In my opinion.
[ February 08, 2007: Message edited by: Jim Yingst ]

Darya Akbari
Ranch Hand
Posts: 1855
Originally posted by Jim Yingst:
Out of curiosity, is there any chance that a duration will ever be greater than 31 days? What would happen then?

There is a chance that the duration becomes greater than 31 days :roll: . And actually I would have to adapt the getDuration method.

Your example looks really better than mine. However your String.format(...) works only in Java 1.5 .

Darya Akbari
Ranch Hand
Posts: 1855
Originally posted by Jim Yingst:
What other formats do you think might be necessary? 12-hour clocks to display a duration of 13:00:00 as 01:00:00 PM? You've already hard-coded in the format you're using here anyway.

The format stuff is crucial in my decision why I took my first approach. I should have mentioned that I work under Java 1.4 and am not able to use this wonderful String.format(...) which definitely makes life easier but only in a Java 1.5 world .

Having not that String.format feature in 1.4 make things again difficult because now you have to work around a lot to get the format features as in my approach. There I can easily change the pattern without care of padding or not like HH:MM or H:M etc.
[ February 08, 2007: Message edited by: Darya Akbari ]

Jim Yingst
Wanderer
Sheriff
Posts: 18671
[Darya]: However your String.format(...) works only in Java 1.5

Not true! It also works in 1.6.

All right, it's a little more work without String.format(), but not that much. Just change the last line to:

Darya Akbari
Ranch Hand
Posts: 1855
Great . That made it round, thanks a lot.