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]
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? –