Calculating a time duration with Joda-Time

11.9k views Asked by At

I'm trying to use Joda-Time in order to know time durations between two points in time, where each point is given in its own local timezone.

E.g. :

DateTime ny = new DateTime(2011, 2, 2, 7, 0, 0, 0, DateTimeZone.forID("America/New_York"));
DateTime la = new DateTime(2011, 2, 3, 10, 15, 0, 0, DateTimeZone.forID("America/Los_Angeles"));
DateTime utc1 = ny.withZone(DateTimeZone.UTC);
DateTime utc2 = la.withZone(DateTimeZone.UTC);        
Period period = new Period(utc1, utc2);

Now, I wish to know if this takes into account day light savings and leap years... Also, is the use of 'Period' the correct Joda-Time way to achieve this? Thanks ;)

2

There are 2 answers

0
Russ Hayward On BEST ANSWER

The code you provided will work and take into account time zones but you don't need to do the conversion to UTC. This code is simpler and does the same thing (using a Duration rather than a Period):

DateTime ny = new DateTime(2011, 2, 2, 7, 0, 0, 0, DateTimeZone.forID("America/New_York"));
DateTime la = new DateTime(2011, 2, 3, 10, 15, 0, 0, DateTimeZone.forID("America/Los_Angeles"));
Duration duration = new Interval(ny, la).toDuration();
0
fcarlsen On

Depending on how you use it, the code above may not be a good idea.

All DateTime constructors that take int's for year/month/day/hour etc are vulnerable to the Daylight Savings (DST) transition periods, in which case Joda-time will throw an exception. So if the hour during transition is a possible input in your application, it will fail:

DateTime ny = new DateTime(2011, 3, 13, 2, 0, 0, 0, DateTimeZone.forID("America/New_York"));

Exception in thread "main" java.lang.IllegalArgumentException: Illegal instant due to time zone offset transition: 2011-03-13T07:00:00.000
at org.joda.time.chrono.ZonedChronology.localToUTC(ZonedChronology.java:143)
at org.joda.time.chrono.ZonedChronology.getDateTimeMillis(ZonedChronology.java:119)
at org.joda.time.chrono.AssembledChronology.getDateTimeMillis(AssembledChronology.java:133)
at org.joda.time.base.BaseDateTime.<init>(BaseDateTime.java:254)
at org.joda.time.base.BaseDateTime.<init>(BaseDateTime.java:223)
at org.joda.time.DateTime.<init>(DateTime.java:264)

Similarly, you'll face another problem in the fall, when it's not possible to determine which hour is referred to *as there will be 2 * 2o'clock in the given timezone. The DateTime methods withHourOfday and withTime are vulnerable to the same issue, as well as parsing datetimes as strings with timezones that are affected by DST.

Possible workarounds include

  • instantiating with any fixed-offset timezone instead (such as UTC)
  • parsing same as a string with a UTC timezone
  • instantiating a valid time in the local time zone (e.g. midnight) and using plusHours to move forward till the desired time
  • have a guard (if-statement) to protect against the second hour of the transition dates
  • catch the exception and check when the next transition is going to happen (using DateTimeZone.nextTransition), and move back/forward accordingly