2016-07-29 23 views
1

Mit Spring MVC (Frühjahr Boot) analysieren ich ZonedDateTime vonJackson: ZonedDateTime mit Zeitzone id

2016-07-26T05:30:47+01:00 

, aber nicht von

2016-07-26T05:30:47+01:00 Europe/Paris 

Wie kann ich Zeitzone explizit hinzufügen und noch in der Lage sein deserialisieren kann es deserialisieren?

+0

Der Begriff "Europa/Paris" bezeichnet eine vollständige Zeitzone mit allen Übergangszeiten, aktuellen und zukünftigen Regeln für die Sommerzeit und der Version der zugrunde liegenden Zeitzonendaten. Also würde das Serialisieren und Deserialisieren möglicherweise all diese Dinge übertragen müssen, nicht nur die Zeichenfolge "Europe/Paris". Meiner Meinung nach ist es keine gute Idee, alle zu serialisieren. Haben Sie darüber nachgedacht, den Instant von 'ZonedDateTime' nur zu serialisieren, um eine bessere Leistung sicherzustellen? –

Antwort

0

Sie können ein Muster mit einem optionalen Abschnitt angeben (durch [] abgegrenzt), um anzugeben, dass ein Feld optional ist, und es mithilfe der @JsonFormat-Annotation zu dem entsprechenden Feld hinzufügen.

Nehmen wir zum Beispiel diese Klasse:

public class OptionalTimeZoneTest { 

    @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssXXX[ VV]") 
    private ZonedDateTime date; 

    // getter and setter 
} 

Hinweis, den letzten Teil ([ VV]): Das Muster innerhalb [] ist ein optionaler Abschnitt, so dass der Parser es zu analysieren versucht, falls vorhanden. Und das Muster VV ist die Zone-ID (oder Zeitzone Namen, um weitere Informationen, werfen Sie einen Blick auf die javadoc)

Damit können beide Formate lesen:

ObjectMapper mapper = new ObjectMapper(); 
mapper.registerModule(new JavaTimeModule()); 
// add this to preserve the same offset (don't convert to UTC) 
mapper.configure(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE, false); 

// without timezone 
String json = "{ \"date\": \"2016-07-26T05:30:47+01:00\" }"; 
OptionalTimeZoneTest value = mapper.readValue(json, OptionalTimeZoneTest.class); 
System.out.println(value.getDate()); // 2016-07-26T05:30:47+01:00 

// with timezone 
json = "{ \"date\": \"2016-07-26T05:30:47+01:00 Europe/Paris\" }"; 
value = mapper.readValue(json, OptionalTimeZoneTest.class); 
System.out.println(value.getDate()); // 2016-07-26T05:30:47+02:00[Europe/Paris] 

Die Ausgabe lautet:

2016-07-26T05: 30: 47 + 01: 00
2016-07-26T05: 30: 47 + 02: 00 [Europa/Paris]

Beachten Sie, dass im ersten Fall die Ausgabe 2016-07-26T05:30:47+01:00 ist (weil es keine Zeitzone hat, also wird der +01:00 Offset angewendet).

aber im zweiten Fall ist der Ausgang 2016-07-26T05:30:47+02:00[Europe/Paris], weil in Europe/Paris Zeitzone, 26/07/2016 is summer-time (so ist der Versatz +02:00). Und die java.time API wurde in einer Weise implementiert, dass die Zeitzone Vorrang hat, wenn ein solcher String analysiert wird.


Wenn Sie möchten, dass alle ZonedDateTime Instanzen UTC konvertiert werden, können Sie diese Zeile entfernen:

mapper.configure(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE, false); 

Ohne sie wird die Daten zu UTC umgewandelt werden, und der Ausgang wird sein:

2016-07-26T04: 30: 47Z [UTC]
2016-07-26T03: 30: 47Z [UTC]