2011-11-17 4 views
3

두 클래스가 있습니다. 첫 번째는 달력 필드와 정수 필드 (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 일, GMT + 1 월 11 일, GMT + 1)를 설정했습니다.

데비안 레니, TZ가 CET이다 :

시스템 TZ에 따라서는 (GMT TZ)에서 다른 결과를 도시

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

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 아파치 평민 - 랭 LIB에서 org.apache.commons.lang.SerializationUtils입니다.

+0

테스트 케이스를 조금 단순화 할 수 있습니까? firstClass와 secondClass 및 SerializationUtils를 가져옵니다. – Thilo

+0

@Thilo 업데이트를 참조하십시오. – ninja

답변

1

(Calendar) SerializationUtils.clone (firstClass.getDepartureDatetime())을 호출하면 Timezone에 문제가있었습니다. 시간대가 서버 TZ로 설정되었으며 비교하는 동안 몇 시간이 걸렸습니다.

0

먼저 질문해야 할 질문 : 내가 무엇을하려고합니까?

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

그러나 그것은 문제의 핵심이 될 것 같지 않습니다 해 GregorianCalendar와의 XMLGregorianCalendar를 변환하는 것은 간단합니다. 시간대 변환을 수행하려고하십니까? IMHO thes는 전환을 표시 시간으로 이동하면 (실제로 형식 문제이므로) 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를 완전히 폐지 할 수 있으며 공항에서 미국 시간대를 전환 할 수도 있습니다. 카운티가 동부에서 중부로 그리고 뒤로 이동한다는 것은 생각보다 자주 발생합니다.) 이를 해결하려면 컴퓨터의 Locale 데이터베이스를 사용해야하며 자신의 시간대 산술을 롤에 넣지 마십시오.

관련 문제