2011-11-17 21 views
3

我有2個類。首先包含日曆字段和整數字段(tz偏移量)。其次包含XmlGregorianCalendar字段。我想比較從第一級到第二級的日期。將XMLGregorianCalendar轉換爲GregorianCalendar的正確方法

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:00 GMT + 1)。

根據系統TZ它示出了不同的結果(在GMT TZ):

的Debian萊尼,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! 

我在做什麼錯了?

謝謝。

UPDATE

第一和第二類:

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是Apache公地琅LIB的org.apache.commons.lang.SerializationUtils。

+0

你可以簡化那個測試案例嗎?取出firstClass和secondClass和SerializationUtils.clone – Thilo

+0

@Thilo查看更新 – ninja

回答

1

當我們調用(Calendar)SerializationUtils.clone(firstClass.getDepartureDatetime())時,這是Timezone的問題。時區設置爲服務器TZ,我們在比較過程中損失了幾個小時。

0

你應該問自己的第一個問題:我想要做什麼?轉換GregorianCalendar和XMLGregorianCalendar很容易:

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

但是,這似乎不是你的問題的核心。您是否嘗試執行時區轉換?如果將轉換轉換爲顯示時間(因爲它實際上是一個格式問題),恕我直言,可以更輕鬆地完成恕我直言,可以利用GregorianCalendar和XMLGregorianCalendar隨時隨地攜帶其時區信息並擺脫兩個助手類。

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

或者,也許你的問題是一個真正的消毒輸入問題。我看到你有一個departureTime變量,大概是來自世界各地機場的航班,而且你可能從沒有明確時區信息的一些數據源獲取它們,而是假設「在機場的當地時間」。這將解釋助手類,但在這種情況下,您應該在發生的情況下清理輸入。確定「機場當地時間」有時可能會很棘手(一個國家可能會選擇明年一週後從夏令時轉換到標準,或者完全取消DST,並且機場甚至可能會在美國切換時區,從東部移到中部和後面的縣比你想象的更頻繁)。您應該使用計算機的語言環境數據庫來解決該問題,並避免嘗試推出自己的時區算術。

相關問題