Estoy buscando un método simple para convertir entre java.util.Date y javax.xml.datatype.XMLGregorianCalendar en ambas direcciones.
Aquí está el código que estoy usando ahora :
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();
}
}
}
¿Hay algo más simple, como alguna llamada API que he pasado por alto?
La conversión entre una fecha / hora XML estándar y un objeto de fecha Java parece una tarea bastante rutinaria y me sorprende que tenga que escribir este código.
¿Alguna sugerencia?
NOTAS: Mis clases JAXB se generan automáticamente a partir de un esquema. El proceso de compilación de mi proyecto no me permite realizar cambios manuales en las clases generadas. XJC genera los elementos xs: dateTime como XMLGregorianCalendar en las clases JAXB. El esquema se amplía y modifica periódicamente, por lo que se me permite realizar cambios limitados en el archivo XSD del esquema.
ACTUALIZACIÓN DE LA SOLUCIÓN: La solución propuesta por Blaise me ha permitido sacar XMLGregorianCalendar de la mezcla y ocuparme de los objetos java.util.Calendar en su lugar. Al agregar una cláusula de enlace JAXB en la parte superior de mi archivo de esquema, XJC puede generar asignaciones más apropiadas para xs: dateTime en mis clases JAXB. Aquí hay algunos fragmentos que muestran las modificaciones en mi archivo XSD.
El elemento raíz en el archivo 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">
Bloque de anotación de enlace JAXB, insertado inmediatamente después del elemento raíz en 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>
Dado que el campo XML xs: dateTime también almacena la zona horaria, podría ser mejor para mí trabajar con Calendar en lugar de Date de todos modos, ya que los objetos Calendar tienen una API bastante buena para trabajar con configuraciones regionales y zonas horarias. En cualquier caso, estoy mucho más feliz de tratar con objetos Calendar en lugar de XMLGregorianCalendar. Ya no es necesario los métodos de conversión que enumeré anteriormente. No llegué hasta java.util.Date, ¡pero lo suficientemente cerca!
util
paquete y úsalo.Respuestas:
¿Por qué no usar un archivo de enlace externo para decirle a XJC que genere campos java.util.Date en lugar de XMLGregorianCalendar?
Consulte también ¿Cómo asigno xs: date a java.util.Date? Blog
fuente
De XMLGregorianCalendar a java.util.Date, simplemente puede hacer:
fuente
Desde java.util.Date a XMLGregorianCalendar, simplemente puede hacer:
Código editado después del primer comentario de @ f-puras, porque cometí un error.
fuente
Tuve que hacer algunos cambios para que funcionara, ya que algunas cosas parecen haber cambiado mientras tanto:
Aquí hay un ejemplo funcional, espero que esto ayude (estoy usando JodaTime pero en este caso SimpleDate sería suficiente):
En el xsd, he seguido las excelentes referencias dadas anteriormente, por lo que he incluido esta anotación xml:
fuente
Yo también tenía este tipo de dolor de cabeza. Me deshice de él simplemente representando los campos de tiempo como primitivos largos en mi POJO. Ahora la generación de mi código de cliente WS maneja todo correctamente y no más basura de XML a Java. Y, por supuesto, tratar con millis en el lado de Java es simple e indoloro. ¡El principio de KISS es genial!
fuente
Puede utilizar esta personalización para cambiar la asignación predeterminada a java.util.Date
fuente
Personalización del calendario y la fecha durante la clasificación
Paso 1: Prepare jaxb binding xml para propiedades personalizadas, en este caso me preparé para la fecha y el calendario
Setp 2: agregue un archivo de enlace jaxb personalizado a Apache o cualquier complemento relacionado en la opción xsd como se menciona a continuación
Setp 3: escriba el código para la clase CalendarConverter
Setp 4: Salida
fuente