2013-10-18 3 views
5

Sto provando a serializzare e quindi deserializzare un oggetto DateTime Joda usando Jackson, ma non deserializza completamente l'oggetto. Sembra che le informazioni sul fuso orario siano perse.Jackson perde l'offset dell'ora dalle date di deserializzazione a JodaTime

Questo codice:

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

Risulterà:

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 

È questo disegno? C'è qualcosa che posso fare qui, a meno di scrivere il mio serializzatore/deserializzatore? Ho visto alcune domande su questo su SO, ma nessuno che si occupi specificamente di questo aspetto.

sto usando Joda 2.1 e Jackson 2.1

risposta

6

Sì, questo è di progettazione. JodaTime DateTimeSerializer utilizza il metodo toString() standard. Secondo JodaTime official guidetoString() restituisce - la stringa standard ISO8601 per DateTime. Inoltre, lo standard DateTimeDeserializer crea sempre i datet UTC.

Per memorizzare TimeZone è necessario archiviarlo separatamente con lo stesso json e utilizzare il metodo .withZone() dopo la deserializzazione o semplicemente creare serializzatore e deserializzatore.

UPDATE

versione 2.2.3 ha un comportamento esteso po '- DateTimeDeserializer crea DateTime con fuso orario preso da DeserializationContext. può essere cambiato con ObjectMapper.setTimeZone(). Di default è TimeZone.getTimeZone("GMT")

+1

Quindi c'è un intero modulo dedicato alla gestione degli oggetti Joda, ma esegue la serializzazione nel modo più semplicistico possibile, non riuscendo a conservare le informazioni cruciali ... Questo è un peccato. Sembra che dovrò scrivere il mio deserializzatore. – Vysarat

+2

Invece di lamentarti, hai effettivamente provato a contattare gli autori del modulo, offrendo il tuo aiuto? La lagnanza di SO non è un modo produttivo per lavorare con i progetti OSS. – StaxMan

1

Da the Javadoc for AbstractInstant#equals() che è una superclasse di DateTime:

confronta questo oggetto con l'oggetto specificato per l'uguaglianza in base all'istante millisecondo, cronologia e fuso orario. (la mia enfasi)

Due oggetti che rappresentano lo stesso istante di tempo, ma si trovano in fusi orari diversi (in base all'ID del fuso orario), saranno considerati diversi. Solo due oggetti con lo stesso DateTimeZone, Chronology e instant sono uguali.

Le due date che visualizzi designano lo stesso istante, ma poiché hanno fusi orari diversi, JodaTime dice che non sono "uguali". Non vedo nulla di sbagliato nel modo in cui Jackson li sta trattando.

+0

destro, non sono uguali perché Jackson non è deserializzazione il fuso orario, che mi aspetterei che facesse. – Vysarat

4

Jackson deve essere detto di non regolare il fuso orario a quella del contesto locale:

mapper.disable(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE); 

See this issue on GitHub