Estou procurando um método simples de conversão entre java.util.Date e javax.xml.datatype.XMLGregorianCalendar em ambas as direções.
Aqui está o código que estou usando agora :
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();
}
}
}
Existe algo mais simples, como alguma chamada de API que esqueci?
A conversão entre uma data / hora XML padrão e um objeto de data Java parece uma tarefa bastante rotineira e estou surpreso por ter que escrever este código.
Alguma sugestão?
NOTAS: Minhas classes JAXB são geradas automaticamente a partir de um esquema. O processo de construção em meu projeto não permite que eu faça alterações manuais nas classes geradas. Os elementos xs: dateTime estão sendo gerados por XJC como XMLGregorianCalendar nas classes JAXB. O esquema é estendido e ajustado periodicamente, portanto, tenho permissão para fazer alterações limitadas no arquivo XSD do esquema.
ATUALIZAÇÃO NA SOLUÇÃO: A solução proposta por Blaise me permitiu tirar XMLGregorianCalendar da mistura e lidar com objetos java.util.Calendar. Adicionando uma cláusula de ligação JAXB na parte superior do meu arquivo de esquema, o XJC é capaz de gerar mapeamentos mais apropriados para xs: dateTime em minhas classes JAXB. Aqui estão alguns trechos que mostram as modificações em meu arquivo XSD.
O elemento raiz no arquivo XSD:
<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">
Bloco de anotação de ligação JAXB, inserido imediatamente após o elemento raiz em 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>
Como o campo XML xs: dateTime também armazena fuso horário, pode ser melhor para mim trabalhar com Calendário em vez de Data de qualquer maneira, já que os objetos Calendar têm uma API muito boa para trabalhar com localidades e fusos horários. Em qualquer caso, fico muito mais feliz em lidar com objetos Calendar em vez de XMLGregorianCalendar. Não há mais necessidade dos métodos de conversão que listei acima. Não cheguei até java.util.Date, mas perto o suficiente!
util
pacote e usá-lo.