Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to handle jodatime Illegal instant due to time zone offset transition

Tags:

java

jodatime

I want to set up joda DateTime to today at 2 AM (see sample code below). But I'm getting this exception:

Exception in thread "main" org.joda.time.IllegalFieldValueException: Value 2 for hourOfDay is not supported: Illegal instant due to time zone offset transition: 2011-03-27T02:52:05.239 (Europe/Prague) at org.joda.time.chrono.ZonedChronology$ZonedDateTimeField.set(ZonedChronology.java:469) at org.joda.time.MutableDateTime.setHourOfDay(MutableDateTime.java:702) 

What is the correct way to the handle exception above or to create a DateTime at a particular hour of day?

Sample code:

MutableDateTime now = new MutableDateTime(); now.setHourOfDay(2); now.setMinuteOfHour(0); now.setSecondOfMinute(0); now.setMillisOfSecond(0); DateTime myDate = now.toDateTime(); 

Thanks.

like image 793
michal.kreuzman Avatar asked Mar 27 '11 18:03

michal.kreuzman


1 Answers

It seems like you're trying to get from a specific local time to a DateTime instance and you want that to be robust against daylight savings. Try this... (note I'm in US/Eastern, so our transition date was 13 Mar 11; I had to find the right date to get the exception you got today. Updated my code below for CET, which transitions today.) The insight here is that Joda provides LocalDateTime to let you reason about a local wall-clock setting and whether it's legal in your timezone or not. In this case, I just add an hour if the time doesn't exist (your application has to decide if this is the right policy.)

import org.joda.time.DateTime; import org.joda.time.DateTimeZone; import org.joda.time.LocalDateTime;  class TestTz {    public static void main(String[] args)   {      final DateTimeZone dtz = DateTimeZone.forID("CET");      LocalDateTime ldt = new LocalDateTime(dtz)        .withYear(2011)        .withMonthOfYear(3)        .withDayOfMonth(27)        .withHourOfDay(2);      // this is just here to illustrate I'm solving the problem;      // don't need in operational code     try {       DateTime myDateBorken = ldt.toDateTime(dtz);     } catch (IllegalArgumentException iae) {       System.out.println("Sure enough, invalid instant due to time zone offset transition!");     }      if (dtz.isLocalDateTimeGap(ldt)) {       ldt = ldt.withHourOfDay(3);     }      DateTime myDate = ldt.toDateTime(dtz);     System.out.println("No problem: "+myDate);   }  } 

This code produces:

 Sure enough, invalid instant due to time zone offset transition! No problem: 2011-03-27T03:00:00.000+02:00 
like image 166
andersoj Avatar answered Sep 29 '22 14:09

andersoj