As you may know, JAX-WS uses javax.xml.datatype.XMLGregorianCalendar abstract class in order to present date/time data type fields. We have used this class rather long time in happy ignorance without of any problem. Suddenly, few days ago, we ran into a weird bug of its Sun’s implementation (com.sun.org.apache.xerces.internal.jaxp.datatype.XMLGregorianCalendarImpl). The bug appears whenever we try to convert an XMLGregorianCalendar instance to a java.util.GregorianCalendar using toGregorianCalendar() method. I’ve written a simple JUnit test in order to demonstrate this bug:
javax.xml.datatype.XMLGregorianCalendar
com.sun.org.apache.xerces.internal.jaxp.datatype.XMLGregorianCalendarImpl
XMLGregorianCalendar
java.util.GregorianCalendar
toGregorianCalendar()
@Test public void testXMLGregorianCalendar() throws Exception { SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); XMLGregorianCalendar calendar = javax.xml.datatype.DatatypeFactory.newInstance().newXMLGregorianCalendar(); calendar.setDay(1); calendar.setMonth(1); calendar.setYear(1); System.out.println("1: " + calendar.toString()); System.out.println("2: " + formatter.format(calendar.toGregorianCalendar().getTime())); GregorianCalendar cal = new GregorianCalendar( calendar.getYear(), calendar.getMonth() - 1, calendar.getDay()); cal.clear(Calendar.AM_PM); cal.clear(Calendar.HOUR_OF_DAY); cal.clear(Calendar.HOUR); cal.clear(Calendar.MINUTE); cal.clear(Calendar.SECOND); cal.clear(Calendar.MILLISECOND); System.out.println("3: " + formatter.format(cal.getTime())); /* * Output: * * 1: 0001-01-01 * 2: 0001-01-03 00:00:00 * 3: 0001-01-01 00:00:00 */ }
As you see, the date 0001-01-01 is transformed to 0001-01-03 after call of toGregorianCalendar() method (see output 2).
Moreover, if we’ll serialize this XMLGregorianCalendar instance to XML we’ll see it as 0001-01-01+02:00 which is rather weird and could be potential problem for interoperability between Java and other platforms.
Conclusion: in order to convert XMLGregorianCalendar value to GregorianCalendar do the following. Create a new instance of GregorianCalendar and just set the corresponding fields with values from XMLGregorianCalendar instance.
GregorianCalendar
Remember Me
a@href@title, b, blockquote@cite, em, i, strike, strong, sub, super, u