Question

I have 2 classes. First contains Calendar field and Integer field (tz offset). Second contains XmlGregorianCalendar field. I want to compare date from firs class to date from second.

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()) + "]");
}

I've set equal dates (Nov 19, 9:00 AM GMT+1) in that classes.

Depending on the system TZ it shows different results (in GMT TZ):

Debian Lenny, TZ is CET:

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

Win7, TZ is GMT+3:

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

What I'm doing wrong?

Thanks.

UPDATE

1st and 2nd classes:

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 is an org.apache.commons.lang.SerializationUtils from Apache commons-lang lib.

Was it helpful?

Solution

It was a problem with Timezone when we call (Calendar) SerializationUtils.clone(firstClass.getDepartureDatetime()). Timezone was set to the server TZ and we lost some hours during comparing.

OTHER TIPS

The first question you should ask yourself: What am i trying to do? Converting GregorianCalendar and XMLGregorianCalendar is easy:

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

But that doesn't seem to be the core of your problem. Are you trying to perform time zone conversions? IMHO thes can be done more easily if you shift the conversion to the display time (since it's really a formatting issue), make use of the fact that both GregorianCalendar and XMLGregorianCalendar carry their time zone information with them and get rid of the two helper classes.

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);
}

Or maybe your problem is really an issue of sanitizing the input. I see you have a departureTime variable, presumably for flights from airports around the world, and you probably get them from some data source that has no explicit time zone information, and instead assumes "local time at the airport". That would explain the helper classes, but in that case, you should sanitize your input where it happens. Determining "local time at the airport" can be tricky at times (a country might choose to switch from daylight saving time to standard a week later next year, or abolish DST altogether, and an airport might even switch timezones in the US, for example, counties moving from eastern to central and back happens more frequently than you'd think). You should use your computer's Locale database to resolve that, and avoid trying to roll your own timezone arithmetic.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top