Given a time in milliseconds, we can create XMLGregorianCalendar using the following snippet.
GregorianCalendar greCal = new GregorianCalendar();
greCal.setTimeInMillis(timeInMilliseconds);
XMLGregorianCalendar xmlCal = DatatypeFactory.newInstance().newXMLGregorianCalendar(greCal));
But the problem is, it hits the performance badly.
http://www.java.net/node/666491
There is a bug filed for this with SUN but they have not listed any workarounds. http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6466177
Tried searching for some other alternative but in vain. Do any of you folks have an alternative to do the same?
Thanks
Raman
XML Gregorian Calendar: The rules for specifying dates in XML format are defined in the XML Schema standard. The Java XMLGregorianCalendar class, introduced in Java 1.5, is a representation of the W3C XML Schema 1.0 date/time datatypes and is required to use the XML format.
Create a new XMLGregorianCalendar by parsing the String as a lexical representation. Create a Java representation of XML Schema builtin datatype date or g* . Create a Java instance of XML Schema builtin datatype time. Create a Java instance of XML Schema builtin datatype time .
DatatypeFactory ", exists, a class with the name of the property's value is instantiated. Any Exception thrown during the instantiation process is wrapped as a DatatypeConfigurationException . If the file ${JAVA_HOME}/lib/jaxp. properties exists, it is loaded in a Properties Object .
The expensive part is DatatypeFactory.newInstance(), it shows right on top when profiling the application. In our case we stored the DatatypeFactory as static variable and we were able to circumvent the repeated initialization. This should work because the DatatypeFactory implementation we use is supposed to be thread safe (as stated in the bug report). I agree that there's a chance that this may change depending on the implementation used. So I'll recommend to doublecheck.
private static DatatypeFactory datatypeFactory;
static{
try {
datatypeFactory = DatatypeFactory.newInstance();
} catch (DatatypeConfigurationException e) {
throw new RuntimeException("Init Error!", e);
}
}
public void foo(long timeInMilliseconds){
GregorianCalendar greCal = new GregorianCalendar(); greCal.setTimeInMillis(timeInMilliseconds);
XMLGregorianCalendar xmlGregorienCalendar = datatypeFactory.newXMLGregorianCalendar(greCal);
// ...
}
Since as @VivaceVivo mentioned DataFactory.newInstance() is expensive and impl not guaranteed to be thread-safe, consider using a ThreadLocal:
final private static ThreadLocal<DatatypeFactory> datatypeFactoryHolder = new ThreadLocal<DatatypeFactory>()
{
@Override
protected DatatypeFactory initialValue()
{
try
{
return DatatypeFactory.newInstance();
} catch (DatatypeConfigurationException e)
{
throw new IllegalStateException("failed to create " + DatatypeFactory.class.getSimpleName(), e);
}
}
};
public static XMLGregorianCalendar dateToXMLGregorianCalendar(Date date)
{
GregorianCalendar c = new GregorianCalendar();
c.setTime(date);
return datatypeFactoryHolder.get().newXMLGregorianCalendar(c);
}
}
..as long as you don't care if threads retain an extra object or have a way of clearing ThreadLocalMap when needed
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