2013-10-18 38 views
5

我試圖序列化,然後反序列化使用傑克遜Joda DateTime對象,但它並沒有完全反序列化對象。它看起來像時區信息丟失。傑克遜從反序列化JodaTime失去日期的時間偏移

此代碼:

ObjectMapper mapper = new ObjectMapper(); 
mapper.registerModule(new JodaModule()); 
mapper.configure(com.fasterxml.jackson.databind.SerializationFeature.WRITE_DATES_AS_TIMESTAMPS , false); 

DateTime dt = DateTime.now(); 
String j = mapper.writeValueAsString(dt); 
DateTime dt2 = mapper.readValue(j, DateTime.class); 

System.out.println("json: " + j); 
System.out.println("eq? " + (dt.equals(dt2))); 
System.out.println("dates:\n" + dt + "\n" + dt2); 

輸出這樣的:

json: "2013-10-18T14:10:52.458-07:00" 
eq? false 
dates: 
2013-10-18T14:10:52.458-07:00 
2013-10-18T21:10:52.458Z 

設計是這樣嗎?有沒有什麼我可以在這裏做,而不是寫我自己的串行器/解串器? 我在SO上看到了一些關於這個問題的問題,但沒有一個具體處理這方面的問題。

我使用約達2.1和2.1傑克遜

回答

6

是的,這是設計。 JodaTime DateTimeSerializer使用標準的toString()方法。根據JodaTime official guidetoString()返回 - DateTime的標準ISO8601字符串。此外,標準DateTimeDeserializer始終創建UTC日期時間。

要存儲TimeZone,您需要使用相同的json單獨存儲它,並在反序列化之後使用.withZone()方法,或者只創建串行器和解串器。

UPDATE

版本2.2.3有位擴展行爲 - DateTimeDeserializerDeserializationContext採取的timeZone創建日期時間。它可能會改變ObjectMapper.setTimeZone()。默認值是TimeZone.getTimeZone("GMT")

+1

因此,有一個專門處理Joda對象的整個單獨模塊,但它儘可能以最簡單的方式進行序列化,無法保留關鍵信息... 這是一種恥辱。看起來我必須寫我自己的解串器。 – Vysarat

+2

不是抱怨,你真的試圖聯繫模塊的作者,提供你的幫助嗎?對SO進行抱怨並不是與OSS項目合作的有效方式。 – StaxMan

1

the Javadoc for AbstractInstant#equals()這是DateTime超類:

比較的基礎上爲毫秒瞬間平等指定的對象這個對象,年表和時區。 (我的強調)

兩個代表相同時刻但時間不同的對象(基於時區ID)將被視爲不同。只有兩個具有相同DateTimeZone,Chronology和instant的對象是相等的。

你展示的兩個日期指定同一個時刻,但由於他們有不同的時區JodaTime說他們不是「平等的」。我沒有看到傑克遜如何處理他們的問題。

+0

權,他們不相等的,因爲傑克遜不反序列化這是我期望它做的時區。 – Vysarat

4

傑克遜必須被告知沒有時區調整到當地環境的:

mapper.disable(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE); 

See this issue on GitHub