Bug in SimpleTypeBindings marshallTimeZone
cbax007 Jun 21, 2006 4:38 PMThere is a bug in the marshallTimeZone method of the org.jboss.xb.binding.SimpleTypeBindings class. Specifically, it does not take daylight savings properly into account when creating the time zone offset. This can be clearly demonstrated with the following test code:
Calendar c = Calendar.getInstance(); System.out.println("June date object: " + c.getTime()); String datestring = SimpleTypeBindings.marshalDateTime(c); System.out.println("June datestring: " + datestring); Calendar c2 = SimpleTypeBindings.unmarshalDateTime(datestring); System.out.println("June unmarshalled date object: " + c2.getTime()); System.out.println(); c.set(Calendar.MONTH, Calendar.NOVEMBER); System.out.println("Nov date object: " + c.getTime()); datestring = SimpleTypeBindings.marshalDateTime(c); System.out.println("Nov datestring: " + datestring); c2 = SimpleTypeBindings.unmarshalDateTime(datestring); System.out.println("Nov unmarshalled date object: " + c2.getTime());
The output from that code is as follows:
June date object: Wed Jun 21 13:29:45 PDT 2006 June datestring: 2006-06-21T13:29:45.689-08:00 June unmarshalled date object: Wed Jun 21 14:29:45 PDT 2006 Nov date object: Tue Nov 21 13:29:45 PST 2006 Nov datestring: 2006-11-21T13:29:45.689-08:00 Nov unmarshalled date object: Tue Nov 21 13:29:45 PST 2006
You can clearly see that when handling a Date that falls into daylight savings time, that hour is not properly accounted for when creating the time zone offset, thus adding an hour to the Date after it is unmarshalled from a String. To correct this problem, I propose modifying the marshallTimeZone method to be as follows:
private static String marshalTimeZone(Calendar cal) { TimeZone value = cal.getTimeZone(); int offset = value.getRawOffset(); if(offset == 0) { return "Z"; } DecimalFormat hourFormat = new DecimalFormat("'+'00;-00"); DecimalFormat minuteFormat = new DecimalFormat("00"); int minutes = (int)offset / (1000 * 60); int hours = minutes / 60; minutes -= (hours * 60); if (value.inDaylightTime(cal.getTime())) hours+=1; //account for daylight savings return hourFormat.format(hours) + ":" + minuteFormat.format(minutes); }
I changed the signature to take a Calendar object (instead of the TimeZone of that Calendar) and I also added a line just before the last line to account for daylight savings. Now, if I run my previous test, I get the following output:
June date object: Wed Jun 21 13:37:17 PDT 2006 June datestring: 2006-06-21T13:37:17.827-07:00 June unmarshalled date object: Wed Jun 21 13:37:17 PDT 2006 Nov date object: Tue Nov 21 13:37:17 PST 2006 Nov datestring: 2006-11-21T13:37:17.827-08:00 Nov unmarshalled date object: Tue Nov 21 13:37:17 PST 2006
Let me know if this is indeed an issue and if you want me to take out a Jira issue or not.