I'm looking for a simple method of converting between java.util.Date and javax.xml.datatype.XMLGregorianCalendar in both directions.
Here is the code that I'm using now:
import java.util.GregorianCalendar; import javax.xml.datatype.DatatypeConfigurationException; import javax.xml.datatype.DatatypeFactory; import javax.xml.datatype.XMLGregorianCalendar; /** * Utility class for converting between XMLGregorianCalendar and java.util.Date */ public class XMLGregorianCalendarConverter { /** * Needed to create XMLGregorianCalendar instances */ private static DatatypeFactory df = null; static { try { df = DatatypeFactory.newInstance(); } catch (DatatypeConfigurationException dce) { throw new IllegalStateException( "Exception while obtaining DatatypeFactory instance", dce); } } /** * Converts a java.util.Date into an instance of XMLGregorianCalendar * * @param date Instance of java.util.Date or a null reference * @return XMLGregorianCalendar instance whose value is based upon the * value in the date parameter. If the date parameter is null then * this method will simply return null. */ public static XMLGregorianCalendar asXMLGregorianCalendar(java.util.Date date) { if (date == null) { return null; } else { GregorianCalendar gc = new GregorianCalendar(); gc.setTimeInMillis(date.getTime()); return df.newXMLGregorianCalendar(gc); } } /** * Converts an XMLGregorianCalendar to an instance of java.util.Date * * @param xgc Instance of XMLGregorianCalendar or a null reference * @return java.util.Date instance whose value is based upon the * value in the xgc parameter. If the xgc parameter is null then * this method will simply return null. */ public static java.util.Date asDate(XMLGregorianCalendar xgc) { if (xgc == null) { return null; } else { return xgc.toGregorianCalendar().getTime(); } } }
Is there anything simpler, like some API call that I have overlooked?
Converting between a standard XML date/time and a Java date object seems like a pretty routine task and I'm surprised that I have to write this code at all.
Any suggestions?
NOTES: My JAXB classes are autogenerated from a schema. The build process on my project does not allow for me to make manual changes to the generated classes. The xs:dateTime elements are being generated by XJC as XMLGregorianCalendar in the JAXB classes. The schema is extended and tweaked periodically, so I am allowed to make limited changes to the schema XSD file.
UPDATE ON SOLUTION: The solution proposed by Blaise has allowed me to take XMLGregorianCalendar out of the mix and deal with java.util.Calendar objects instead. By adding a JAXB binding clause at the top of my schema file, XJC is able to generate more appropriate mappings for xs:dateTime in my JAXB classes. Here are some snippets that show the modifications in my XSD file.
The root element in the XSD file:
<xs:schema xmlns:mydata="http://my.example.com/mydata" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" targetNamespace="http://my.example.com/mydata" elementFormDefault="unqualified" attributeFormDefault="unqualified" version="0.2" xml:lang="en" jaxb:version="2.0">
JAXB binding annotation block, inserted immediately after root element in XSD:
<xs:annotation> <xs:appinfo> <jaxb:globalBindings> <jaxb:javaType name="java.util.Calendar" xmlType="xs:dateTime" parseMethod="javax.xml.bind.DatatypeConverter.parseDateTime" printMethod="javax.xml.bind.DatatypeConverter.printDateTime" /> </jaxb:globalBindings> </xs:appinfo> </xs:annotation>
Since the XML xs:dateTime field also stores timezone, it might be better for me to work with Calendar instead of Date anyway since Calendar objects have a pretty good API for working with locales and timezones. In any case, I'm much happier to deal with Calendar objects instead of XMLGregorianCalendar. No need for the conversion methods that I listed above anymore. I didn't get all the way to java.util.Date, but close enough!
DatatypeFactory object can convert from GregorianCalendar to XMLGregorianCalendar by calling its newXMLGregorianCalendar method. XMLGregorianCalendar xmlGregCal = DatatypeFactory . newInstance() .
The simplest way to format XMLGregorianCalendar is to first convert it to the Date object, and format the Date to String. XMLGregorianCalendar xCal = ..; //Create instance Date date = xCal. toGregorianCalendar(). getTime(); DateFormat df = new SimpleDateFormat("MM/dd/yyyy hh:mm a z"); String formattedString = df.
The XML Schema standard defines clear rules for specifying dates in XML format. In order to use this format, the Java class XMLGregorianCalendar, introduced in Java 1.5, is a representation of the W3C XML Schema 1.0 date/time datatypes.
From XMLGregorianCalendar to java.util.Date you can simply do:
java.util.Date dt = xmlGregorianCalendarInstance.toGregorianCalendar().getTime();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With