3

2つのクラスがあります。最初に、カレンダーフィールドと整数フィールド(tzオフセット)が含まれます。2番目にはXmlGregorianCalendarフィールドが含まれています。最初のクラスの日付と2番目のクラスの日付を比較したいと思います。

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

そのクラスで同じ日付(11月19日午前9時GMT + 1)を設定しました。

システムTZに応じて、異なる結果が表示されます(GMT TZ)。

Debian Lenny、TZはCETです:

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

Win7、TZはGMT + 3です:

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

私が間違っているのは何ですか?

ありがとう。

アップデート

1番目と2番目のクラス:

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は、Apachecommons-langlibのorg.apache.commons.lang.SerializationUtilsです。

4

2 に答える 2

1

(Calendar) SerializationUtils.clone(firstClass.getDepartureDatetime()) を呼び出すと、タイムゾーンに問題がありました。タイムゾーンはサーバーの TZ に設定されており、比較中に数時間を失いました。

于 2011-11-18T15:56:28.117 に答える
0

自問すべき最初の質問: 私は何をしようとしているのか? GregorianCalendar と XMLGregorianCalendar の変換は簡単です。

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

しかし、それはあなたの問題の核心ではないようです。タイムゾーンの変換を実行しようとしていますか? IMHO thesは、変換を表示時間にシフトすると(実際にはフォーマットの問題であるため)、より簡単に実行できます.GregorianCalendarとXMLGregorianCalendarの両方がタイムゾーン情報を保持し、2つのヘルパークラスを取り除くという事実を利用してください. .

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.

于 2011-11-17T15:07:11.743 に答える