Forma correcta de convertir XMLGregorianCalendar a GregorianCalendar

Tengo 2 clases. La primera contiene el Calendario de campo y campo de Entero (tz offset). Segundo contiene XmlGregorianCalendar campo. Quiero comparar la fecha de firs clase fecha a partir de la segunda.

Calendar cal1 = (Calendar) SerializationUtils.clone(firstClass.getDepartureDatetime());
cal1.add(Calendar.MINUTE, -firstClass.getDepartureTzOffset());

GregorianCalendar cal2 = secondClass.getDepartureDateTime().toGregorianCalendar();
cal2.add(Calendar.MINUTE, -secondClass.getDepartureDateTime().getTimezone());

if (LOGGER.isDebugEnabled()) {
                LOGGER.debug(" - Second  [" + DateFormat.getDateTimeInstance().format(cal2.getTime()) + "]");
                LOGGER.debug(" - First [" + DateFormat.getDateTimeInstance().format(cal1.getTime()) + "]");
}

He establecido la igualdad de fechas (desde el 19 de Noviembre, de 9:00 AM GMT+1) en las clases.

Dependiendo del sistema TZ muestra diferentes resultados (GMT TZ):

Debian Lenny, TZ se CET:

Second  [Nov 19, 2011 7:00:00 AM] - wrong!
First [Nov 19, 2011 8:00:00 AM] -right!

Win7, TZ es GMT+3:

Second  [Nov 19, 2011 8:30:00 AM] - wrong!
First [Nov 19, 2011 8:00:00 AM] -right!

Lo que estoy haciendo mal?

Gracias.

ACTUALIZACIÓN

1ª y 2ª clases:

public class FirstClass implements Serializable {
    private static final long serialVersionUID = -1150341618306402800L;

    private Calendar departureDatetime;

    private Integer departureTzOffset;

    public Calendar getDepartureDatetime() {
        return departureDatetime;
    }

    public void setDepartureDatetime(Calendar departureDatetime) {
        this.departureDatetime = departureDatetime;
    }

    public Integer getDepartureTzOffset() {
        return departureTzOffset;
    }

    public void setDepartureTzOffset(Integer departureTzOffset) {
        this.departureTzOffset = departureTzOffset;
    }
}

public class SecondClass implements Serializable
{

    private final static long serialVersionUID = 12345L;

    protected XMLGregorianCalendar departureDateTime;

    public XMLGregorianCalendar getDepartureDateTime() {
        return departureDateTime;
    }

    public void setDepartureDateTime(XMLGregorianCalendar value) {
        this.departureDateTime = value;
    }
}

SerializationUtils es una org.apache.commons.lang.SerializationUtils de Apache commons-lang lib.

  • se puede simplificar ese caso de prueba un poco? Sacar firstClass y secondClass y SerializationUtils.clon
  • ver la actualización
InformationsquelleAutor ninja | 2011-11-17

2 Kommentare

  1. 1

    Que era un problema con la zona Horaria cuando nos llame al (Calendario) SerializationUtils.clon(firstClass.getDepartureDatetime()). Zona horaria se establece en el servidor TZ y hemos perdido algunas horas durante la comparación.

  2. 0

    La primera pregunta que usted debe preguntarse: ¿Qué estoy tratando de hacer? La conversión de GregorianCalendar y XMLGregorianCalendar es fácil:

    GregorianCalendar gc;
    XMLGregorianCalendar xc;
    gc = xc.toGregorianCalendar();
    xc = DatatypeFactory.newInstance().newXMLGregorianCalendar(gc);

    Pero que no parece ser el núcleo de su problema. Estás tratando de realizar el tiempo de la zona de conversiones? En mi humilde opinión ts se puede hacer más fácilmente en el caso de cambio de la conversión de la pantalla a la vez (ya que es realmente un problema de formato), hacer uso del hecho de que ambos GregorianCalendar y XMLGregorianCalendar llevar su información de zona horaria con ellos y deshacerse de las dos clases de ayuda.

    TimeZone cet = TimeZone.getTimeZone("CET");
    TimeZone utc = TimeZone.getTimeZone("UTC");
    GregorianCalendar gc = new GregorianCalendar();
    DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z");
    
    @Test
    public void testNow() throws DatatypeConfigurationException {
      df.setTimeZone(gc.getTimeZone());
      log.info(" - Gregorian LOCAL [" + df.format(gc.getTime()) + "]");
      df.setTimeZone(cet);
      log.info(" - Gregorian CET [" + df.format(gc.getTime()) + "]");
      df.setTimeZone(utc);
      String gcs = df.format(gc.getTime());
      log.info(" - Gregorian UTC [" + df.format(gc.getTime()) + "]");
      XMLGregorianCalendar xc = DatatypeFactory.newInstance().newXMLGregorianCalendar(gc);
      df.setTimeZone(xc.getTimeZone(0));
      log.info(" - XML RAW [" + df.format(xc.toGregorianCalendar().getTime()) + "]");
      df.setTimeZone(cet);
      log.info(" - XML CET [" + df.format(xc.toGregorianCalendar().getTime()) + "]");
      df.setTimeZone(utc);
      String xcs = df.format(xc.toGregorianCalendar().getTime());
      log.info(" - XML UTC [" + df.format(xc.toGregorianCalendar().getTime()) + "]");
      assertEquals(gcs, xcs);
    }

    O tal vez su problema es realmente un problema de desinfección a la entrada. Veo que tiene un departureTime variable, presumiblemente para vuelos desde los aeropuertos de todo el mundo, y que, probablemente, obtener desde alguna fuente de datos que no tiene tiempo explícito la información de la zona, y en su lugar se supone «la hora local en el aeropuerto». Eso explicaría el ayudante de clases, pero en ese caso, usted debe desinfectar tu entrada donde ocurre. La determinación de «la hora local en el aeropuerto» puede ser complicado a veces (un país puede elegir cambiar de horario de verano para el estándar de una semana más tarde, el próximo año, o la abolición de horario de verano en conjunto, y un aeropuerto podría incluso cambiar las zonas horarias en los estados unidos, por ejemplo, los condados de movimiento desde el este al centro y de regreso sucede con más frecuencia de lo que cabría pensar). Usted debe utilizar su equipo de la configuración Regional de la base de datos para resolver eso, y tratando de evitar a rodar su propia zona horaria de la aritmética.

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea