I am trying to parse datetime strings and create Joda DateTime objects.
My data comes from a legacy database that stores datetime strings without specifying the timezone/offset. Although the timezone/offset of the datetime strings is not stored it is a business rule of the legacy system that all datetimes are stored in Eastern Time. Unfortunately I do not have the authority to update the way in which the legacy DB stores datetime strings.
Thus, I parse the datetime strings using JODA's "US/Eastern" time zone.
This approach throws an illegalInstance exception when the dateTime string falls within the hour that "disappears" when daylight savings is switched on.
I've created the following example code to demonstrate this behaviour and to show my proposed workaround.
public class FooBar {
public static final DateTimeZone EST = DateTimeZone.forID("EST");
public static final DateTimeZone EASTERN = DateTimeZone.forID("US/Eastern");
public static final DateTimeFormatter EST_FORMATTER = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss.SSS").withZone(EST);
public static final DateTimeFormatter EASTERN_FORMATTER = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss.SSS").withZone(EASTERN);
public static void main(String[] args) {
final String[] listOfDateTimeStrings = {"2014-03-09 02:00:00.000", "2014-03-08 02:00:00.000"};
System.out.println(" *********** 1st attempt *********** ");
for (String dateTimeString: listOfDateTimeStrings){
try{
final DateTime dateTime = DateTime.parse(dateTimeString, EASTERN_FORMATTER);
System.out.println(dateTime);
}
catch(Exception e){
System.out.println(e.getMessage());
}
}
System.out.println(" *********** 2nd attempt *********** ");
for (String dateTimeString: listOfDateTimeStrings){
try{
final DateTime dateTime = DateTime.parse(dateTimeString, EST_FORMATTER);
System.out.println(dateTime);
}
catch(Exception e){
System.out.println(e.getMessage());
}
}
System.out.println(" *********** 3rd attempt *********** ");
for (String dateTimeString: listOfDateTimeStrings){
try{
DateTime dateTime = DateTime.parse(dateTimeString, EST_FORMATTER);
dateTime = dateTime.withZone(EASTERN);
System.out.println(dateTime);
}
catch(Exception e){
System.out.println(e.getMessage());
}
}
}
}
Output produced:
*********** 1st attempt *********** Cannot parse "2014-03-09 02:00:00.000": Illegal instant due to time zone offset transition (America/New_York) 2014-03-08T02:00:00.000-05:00 *********** 2nd attempt *********** 2014-03-09T02:00:00.000-05:00 2014-03-08T02:00:00.000-05:00 *********** 3rd attempt *********** 2014-03-09T03:00:00.000-04:00 2014-03-08T02:00:00.000-05:00
In the "3rd attempt" I get the expected result: the first datetime has an offset of -04:00. as it falls within the first hour of DST for 2015. The second timestamp has an offset of -05:00 as it falls outside of DST.
Is is safe to do this:
DateTime dateTime = DateTime.parse(dateTimeString, A_FORMATTER_WITH_TIME_ZONE_A);
dateTime = dateTime.withZone(TIME_ZONE_B);
I've tested this code with a few different combinations of datetime strings and time zones (and so far it works for all the test cases), but I was wondering if anyone with more Joda experience can see anything wrong/dangerous in this approach.
Or alternatively: is there a better way of doing handling the time zone offset transition with Joda?