java.util.Fecha a XMLGregorianCalendar

Resuelto mac asked hace 15 años • 10 respuestas

¿No existe una manera conveniente de pasar de java.util.Date a XMLGregorianCalendar?

mac avatar May 08 '09 00:05 mac
Aceptado
GregorianCalendar c = new GregorianCalendar();
c.setTime(yourDate);
XMLGregorianCalendar date2 = DatatypeFactory.newInstance().newXMLGregorianCalendar(c);
Ben Noland avatar May 07 '2009 17:05 Ben Noland

Para aquellos que podrían terminar aquí buscando la conversión opuesta (de XMLGregorianCalendara Date):

XMLGregorianCalendar xcal = <assume this is initialized>;
java.util.Date dt = xcal.toGregorianCalendar().getTime();
Nuno Furtado avatar Jan 04 '2011 15:01 Nuno Furtado

Me gustaría dar un paso atrás y dar una mirada moderna a esta pregunta que data de hace 10 años. Las clases mencionadas Datey XMLGregorianCalendarya son antiguas. Desafío el uso de ellos y ofrezco alternativas.

  • DateSiempre estuvo mal diseñado y tiene más de 20 años. Esto es simple: no lo uses.
  • XMLGregorianCalendarTambién es antiguo y tiene un diseño anticuado. Según tengo entendido, se utilizó para producir fechas y horas en formato XML para documentos XML. Me gusta 2009-05-07T19:05:45.678+02:00o 2009-05-07T17:05:45.678Z. Estos formatos concuerdan lo suficientemente bien con ISO 8601 como para que las clases de java.time, la API moderna de fecha y hora de Java, puedan producirlos, lo cual preferimos.

No es necesaria ninguna conversión

Para muchos (¿la mayoría?) propósitos, el reemplazo moderno de a Dateserá un Instant. An Instantes un punto en el tiempo (tal como a Datees).

    Instant yourInstant = // ...
    System.out.println(yourInstant);

Un ejemplo de resultado de este fragmento:

2009-05-07T17:05:45.678Z

Es lo mismo que la última de mis XMLGregorianCalendarcadenas de ejemplo anteriores. Como la mayoría de ustedes saben, proviene de Instant.toStringser llamado implícitamente por System.out.println. Con java.time, en muchos casos no necesitamos las conversiones que en los viejos tiempos hacíamos entre Date, y otras clases (aunque en algunos casos sí necesitamos conversiones Calendar, XMLGregorianCalendarles mostraré un par en la siguiente sección) .

Controlando el desplazamiento

Ni a Dateni in Instanttienen zona horaria ni desplazamiento UTC. La respuesta previamente aceptada y aún más votada de Ben Noland utiliza la zona horaria predeterminada actual de la JVM para seleccionar el desplazamiento del archivo XMLGregorianCalendar. Para incluir un desplazamiento en un objeto moderno utilizamos un archivo OffsetDateTime. Por ejemplo:

    ZoneId zone = ZoneId.of("America/Asuncion");
    OffsetDateTime dateTime = yourInstant.atZone(zone).toOffsetDateTime();
    System.out.println(dateTime);

2009-05-07T13:05:45.678-04:00

Nuevamente esto se ajusta al formato XML. Si desea volver a utilizar la configuración de zona horaria actual de JVM, configúrela zoneen ZoneId.systemDefault().

¿Qué pasa si necesito absolutamente un XMLGregorianCalendar?

Hay más formas de convertir Instanta XMLGregorianCalendar. Presentaré un par, cada uno con sus pros y sus contras. Primero, así como an XMLGregorianCalendarproduce una cadena como 2009-05-07T17:05:45.678Z, también se puede construir a partir de dicha cadena:

    String dateTimeString = yourInstant.toString();
    XMLGregorianCalendar date2
            = DatatypeFactory.newInstance().newXMLGregorianCalendar(dateTimeString);
    System.out.println(date2);

2009-05-07T17:05:45.678Z

Ventaja: es corto y no creo que dé sorpresas. Desventaja: Para mí, se siente como un desperdicio formatear el instante en una cadena y analizarlo nuevamente.

    ZonedDateTime dateTime = yourInstant.atZone(zone);
    GregorianCalendar c = GregorianCalendar.from(dateTime);
    XMLGregorianCalendar date2 = DatatypeFactory.newInstance().newXMLGregorianCalendar(c);
    System.out.println(date2);

2009-05-07T13:05:45.678-04:00

Ventaja: es la conversión oficial. Controlar el desplazamiento es algo natural. Desventaja: pasa por más pasos y, por lo tanto, es más largo.

¿Qué pasa si tenemos una cita?

Si obtuvo un objeto antiguo Datede una API heredada que no puede permitirse el lujo de cambiar en este momento, conviértalo a Instant:

    Instant i = yourDate.toInstant();
    System.out.println(i);

La salida es la misma que antes:

2009-05-07T17:05:45.678Z

Si desea controlar el desplazamiento, convierta más a an OffsetDateTimede la misma manera que antes.

Si tiene un método antiguo Datey lo necesita absolutamente XMLGregorianCalendar, simplemente use la respuesta de Ben Noland.

Enlaces

  • Tutorial de Oracle: Fecha y hora que explica cómo utilizar java.time.
  • Tipos de datos XSD de fecha y hora en W3Schools.
  • Artículo de Wikipedia: ISO 8601
Anonymous avatar May 26 '2019 11:05 Anonymous

A continuación se muestra un método para convertir de GregorianCalendar a XMLGregorianCalendar; Dejaré la parte de convertir de java.util.Date a GregorianCalendar como ejercicio para ti:

import java.util.GregorianCalendar;

import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;

public class DateTest {

   public static void main(final String[] args) throws Exception {
      GregorianCalendar gcal = new GregorianCalendar();
      XMLGregorianCalendar xgcal = DatatypeFactory.newInstance()
            .newXMLGregorianCalendar(gcal);
      System.out.println(xgcal);
   }

}

EDITAR: Lentamente :-)

sasuke avatar May 07 '2009 17:05 sasuke