2010-11-24 2 views
5

나는 적절한 직렬화 가능 날짜 전용 클래스를 찾고있다. 중앙 시간대의 서버를 보유하고 있으므로 동부의 사용자가 2010-11-23으로 날짜를 입력하고 Pacific의 사용자가 2010-11-23으로 (그리고 그 반대로) 입력하도록하십시오.Joda LocalDate - 여전히 즉석입니까?

java.util.Date은 시간에 민감한 순간이므로 나에게 적합하지 않습니다. 바퀴를 재발 명하고 싶지 않아서, 나는 Joda Time에게 시도를하기로 결정했다. 개요에 따르면 LocalDate은 "시간이없는 현지 날짜를 나타내는 클래스 (시간대 없음)"입니다.

불행히도, 시간대에 독립적이지는 않습니다. 데이터베이스에는 2010-11-23이 있습니다. 서버에서 new LocalDate(java.sql.Date)으로 LocalDate으로 변환합니다. date.toString() 인쇄 2010-11-23.

클라이언트에서 그 직렬화 복원 후

, date.ToString() 인쇄 2010-11-22와 date.getDayOfMonth()는 22이다 그러나 date.toDateTimeAtStartOfDay()는 2010-11-23T00 생산 : 00 : 00.000-08 : 00.

내가 잘못 했나요? Joda에 적절한 날짜 전용 시간대 감식 클래스가 있습니까?

EDIT : 데이터베이스에서 시간대를 구분하지 않는 열 (Postgres에서 DATE)을 사용하고 있습니다. 서버는 데이터베이스와 동일한 시간대에 있으므로 날짜를 잘 읽습니다. 그것은 문제가되지 않습니다. 한 시간대에서 인스턴스화 된 모든 Java 시간 유형에서 동일한 시민 (부분) 날짜 값을 갖는 Java 유형을 찾고 있습니다.

EDIT 2 : 서버에 모든 것이 올바르게로드되고 UTC 시간대가 있습니다. 조사한 결과 나는 ISOChronology의 버그라고 생각합니다. 클라이언트에서는 America/Los_Angeles로 압축을 풉니 다. 그 이유는 serialization이 다음과 같이 이루어지기 때문입니다. transient 필드를 사용하여 행운을 비키는 것이 좋습니다.

+1

시간대를 무시하려면 모든 장소에서 UTC/GMT를 사용할 수 있습니까? –

+0

어떤 Joda 버전을 사용하고 있으며 객체는 어떻게 직렬화됩니까? 표준 Java 직렬화의 경우 Stub 클래스에는 iZone 필드의 "수동"처리를위한 적절한 writeObject/readObject 메소드가 있지만 IIOP, SOAP 또는 객체 인스턴스에서 필드 값을 자동으로 추출하려는 다른 직렬화 구현에서는 실패 할 수 있습니다 . – jarnbjo

+0

@jarnbjo 1.6.2. Serializer는 괜찮습니다. 위에서 지적한 문제는 'Stub.iZone'이 일시적이라는 것입니다. –

답변

3

trasient 위의 스텁 클래스의 시간대는 버그입니다. 수만 건의 테스트 또는 5 년간의 폭넓게 사용되지는 않았다는 사실에 놀라움을 금치 못했습니다. 버그 보고서 https://sourceforge.net/tracker/index.php?func=detail&aid=3117678&group_id=97367&atid=617889

시간대는 Javadoc - http://joda-time.sourceforge.net/apidocs/org/joda/time/LocalDate.html에 정의 된대로 UTC 여야합니다. 다른 표준 시간대를 가져 오기 위해 비 직렬화하면 클래스의 내부 상태가 손상됩니다.

JSR-310은 이러한 종류의 문제가없는 훨씬 뛰어난 내부 설계를 사용합니다.

+0

감사합니다. 절대적으로 시간대를 구분하지 않으려면 항상 UTC이어야한다고 말하고 있다는 것을 정확히 이해합니까? –

+0

내부적으로 생성이 완료되면 연대 기 표준 시간대가 UTC이거나 클래스 invariants가 실패합니다. – JodaStephen

1

new LocalDate(java.sql.Date) 생성자를 사용하는 것이 원인 일 수 있습니다.

대신 new LocalDate(int year, int month, int dayOfMonth)을 사용해보세요.

자세한 내용은 LocalDateJavaDocmanual을 참조하십시오.

+0

, 새 LocalDate (date.getTime())가 작동해야합니다. 생성자 LocalDate (Object)는 얻을 수있는 경우 시간대를 사용하려고 시도합니다. –

+0

나는이 모든 옵션을 제공 할 것이다. 그래도 작동한다면 'LocalDate'가 여전히 시간대에 민감하다는 것을 의미 할 것이므로 매우 조심해야합니다. 그게 내가 피하려고했던 것입니다. –

1

은 데이터베이스에 실제로 인 것을 확인해야합니다. 실제로 절대 시간 소인을 사용하고 있으며 모두 한 시간대에있는 경우 의 값을 구문 분석 한 후 시간대로 변환 한 다음 LocalDate로 변환합니다. 데이터베이스에 문자열이있는 경우 해당 문자열을 구문 분석하고 실제로 얻은 정보를 가져 오는 LocalDate의 생성자를 사용합니다. 당신이 무엇을 하든지, 순간과 날짜 사이에 섞이지 않도록하십시오; 당신이 당신의 문제에서 발견 한 것처럼, 그들은 상호 교환 할 수 없습니다.

+0

업데이트 된 설명보기. –

관련 문제