ISO 8601
Datum + Uhrzeit und Datum
Daten | Interpretation |
---|---|
2007-08-31T16:47+00:00 | 16:47 Uhr am 31. August 2007 in der Zeitzone UTC. |
2007-12-24T18:21Z | 18:21 Uhr am 24. Dezember 2007, ebenfalls in der Zeitzone UTC. |
2009-01-01T12:00:00+01:00 | 12:00:00 Uhr am 1. Januar 2009 in Wien. Also 11 Uhr in UTC. |
2021-05-25 | Handtuchtag 2021 |
UTC lässt sich also durch Subtraktion des Zeitzonenoffsets ermitteln.
java.util.Date enthält immer den Zeitstempel in ms
seit 01.01.1970
UTC.
java.time.Instant entspricht im wesentlichen Date. Daher ist es einfach eine Konvertierung zwischen den beiden vorzunehmen.
// Date -> Instant
Instant instant = Instant.ofEpochMilli(someDate.getTime());
// Instant -> Date
Date.from(instant)
java.time.LocalDateTime enthält im Gegensatz zu Instant und Date die implizit UTC referenzieren keine Zeitzoneninformationen. Es speichert lediglich Tag, Monat, Jahr, Stunde, Minute, …
Daher ist man gezwungen bei der Konvertierung in z.B. Instant die Zeitzoneninformation nachzureichen aus der die Uhrzeit stammt.
// LocalDateTime -> Instant
localDateTime.toInstant(ZoneOffset.UTC)
Serialisierung und Deserialisierung
LocalDateTime
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX")
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
@JsonSerialize(using = LocalDateTimeSerializer.class)
private LocalDateTime dateTime;
LocalDate
@JsonFormat(pattern = "yyyy-MM-dd")
@JsonDeserialize(using = LocalDateDeserializer.class)
@JsonSerialize(using = LocalDateSerializer.class)
private LocalDate until;
Best Practice
Wenn möglich java.util.Date meiden. Es ist nicht böse oder so aber etwas irreführend (enthält auch die Uhrzeit) und die neuen Typen sind viel durchdachter.
Frontend
Daten vom Backend sollten immer UTC referenzieren. Daher muss hier zur Anzeige die Lokale Uhrzeit wiederhergestellt werden. Uhrzeiten die an das Backend geschickt werden sollten in UTC sein.
Backend
Zeitzonen sollten im Backend keine Rolle spielen. Alles sollte konsistent und damit UTC sein.
Im Controller kann ISO 8601 mit
@RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime from
entgegen genommen werden.
Wird wirklich konsistent nur UTC übergeben kann auch einfach zu Date oder Instant konvertiert werden.
Date fromDate = Date.from(from.toInstant(ZoneOffset.UTC));