DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT <http://nagoya.apache.org/bugzilla/show_bug.cgi?id=12541>. ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND INSERTED IN THE BUG DATABASE.
http://nagoya.apache.org/bugzilla/show_bug.cgi?id=12541 Calendar de/serializer does not preserve TimeZone [EMAIL PROTECTED] changed: What |Removed |Added ---------------------------------------------------------------------------- Status|RESOLVED |REOPENED Resolution|WONTFIX | ------- Additional Comments From [EMAIL PROTECTED] 2002-09-20 06:46 ------- OTHER ISSUES ============= The current version of CalendarDeserializer does not work correctly for local times (everything ends up GMT whether it should be or not) or all valid time zones (minutes are meant to be optional according to the spec). In addition, the current version of the code spends much of its time performing validation that is already within the scope of the java DateFormat class. I have replaced the class in my own tree, and offer it here for your use if you are so inclined. My code includes test cases that you may wish to execute against the prior code. Regards, Neil Brennan ============ package org.apache.axis.encoding.ser; import org.apache.axis.utils.JavaUtils; import javax.xml.namespace.QName; import java.text.SimpleDateFormat; import java.text.ParseException; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; import java.util.TimeZone; /** * The CalendarSerializer deserializes a dateTime. * Much of the work is done in the base class. * * @author Sam Ruby ([EMAIL PROTECTED]) * Modified for JAX-RPC @author Rich Scheuerle ([EMAIL PROTECTED]) */ public class CalendarDeserializer extends SimpleDeserializer { // used for local time parsing private static SimpleDateFormat LOCAL = new SimpleDateFormat("yyyy-MM- dd'T'HH:mm:ss.SSS"); // used for GMT time parsing private static SimpleDateFormat ZULU = new SimpleDateFormat("yyyy-MM- dd'T'HH:mm:ss.SSS"); // minimum length of a valid datetime string private static int MINLENGTH = 19; /** * The Deserializer is constructed with the xmlType and * javaType */ public CalendarDeserializer(Class javaType, QName xmlType) { super(javaType, xmlType); } /** * The simple deserializer provides most of the stuff. * We just need to override makeValue(). */ public Object makeValue(String source) { // sanity if (source == null || source.length() == 0) { return null; } // init Calendar calendar = Calendar.getInstance(); // parse for BC boolean bc = false; if (source.charAt(0) == '+') source = source.substring(1); else if (source.charAt(0) == '-') { source = source.substring(1); bc = true; } // parse all valid dates try { calendar.setTime(parseDate(source)); } catch (ParseException e) { throw new NumberFormatException(JavaUtils.getMessage ("badDateTime00")); } // handle BC if (bc) calendar.set(Calendar.ERA, GregorianCalendar.BC); if (super.javaType == Date.class) { return calendar.getTime(); } return calendar; } /** * Parses all valid date formats using abilities of DateFormat class. * * @return date specified. */ private static Date parseDate(String source) throws ParseException { Date date = null; boolean bc = false; if (source == null || source.length() < MINLENGTH) throw new NumberFormatException(JavaUtils.getMessage ("badDateTime00")); if (source.charAt(0) == '+') source = source.substring(1); else if (source.charAt(0) == '-') { source = source.substring(1); bc = true; } // handle milliseconds if (source.indexOf(".") < 0) source = source.substring(0, MINLENGTH) + ".000" + source.substring (MINLENGTH); // handle GMT if (source.toUpperCase().indexOf("Z") >= 0) synchronized(ZULU) { return ZULU.parse(source); } // handle local time synchronized(LOCAL) { date = LOCAL.parse(source); } // time zones only apply to local time date.setTime(date.getTime() + parseTimeZone(source.substring (MINLENGTH))); return date; } /** * Parses time zone information. * * @return time zone offset in milliseconds. */ private static int parseTimeZone(String source) { int hours = 0; int minutes = 0; int pos = 0; if ((pos = source.indexOf("+")) >= 0 || (pos = source.indexOf("-")) >= 0) { if (source.length() < pos+2 || !Character.isDigit(source.charAt (pos+1)) || !Character.isDigit(source.charAt(pos+2))) throw new NumberFormatException(JavaUtils.getMessage ("badTimezone00")); hours = (source.charAt(pos+1)-'0')*10 + source.charAt(pos+2)-'0'; if (source.length() > pos+5) { if (source.charAt(pos+3) != ':' || !Character.isDigit (source.charAt(pos+4)) || !Character.isDigit(source.charAt(pos+5))) throw new NumberFormatException(JavaUtils.getMessage ("badTimezone00")); minutes = (source.charAt(pos+4)-'0')*10 + source.charAt(pos+5)- '0'; } } int milliseconds = (hours * 60 + minutes)* 60 * 1000; return ((pos = source.indexOf("+")) >= 0) ? -milliseconds : milliseconds; } /** * Test cases. */ public static void main(String[] args) throws Exception { SimpleDateFormat DEFAULT = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss.SSS"); System.out.println("date: " + DEFAULT.format(parseDate("2002-09- 16T12:01:07"))); System.out.println("date: " + DEFAULT.format(parseDate("2002-09- 16T12:02:06.123"))); System.out.println("date: " + DEFAULT.format(parseDate("2002-09- 16T12:03:05Z"))); System.out.println("date: " + DEFAULT.format(parseDate("2002-09- 16T12:04:04.123Z"))); System.out.println("date: " + DEFAULT.format(parseDate("2002-09- 16T12:05:03.123-05:00"))); System.out.println("date: " + DEFAULT.format(parseDate("2002-09- 16T12:06:02+10:33"))); System.out.println("date: " + DEFAULT.format(parseDate("2002-09- 16T12:07:01+03"))); } }