-
Notifications
You must be signed in to change notification settings - Fork 0
angular json zeitzonen
Eine beliebte Frage innerhalb einer (Java) REST-Anwendung. Wie übergebe ich Datum und Zeitstempel an das Frontend?
- Brauche ich Zeitzonen?
- Als vorformatierten String. Dann eröffnet sich die Frage, welches Format soll verwendet werden? Soll gleich das Ausgabeformat verwendet werden, wie es der Anwender sieht? Oder eher Javascript freundlich, so dass gleich ein Javascript Date erstellt werden kann?
- Als Unix Timestamp in Millisekunden.
Für diese Fragen habe ich mir ein Beispielprojekt auf Github angelegt. Zu finden unter Springboot Demo. Die Anwendung mit
git clone git@github.com:gluehloch/springboot-demo.git
und
mvn clean package
bauen. Im Anschluss das gepackte Jar mit
java -jar ./target/restdemo-1.0.jar
starten.
Unter der Adresse http://localhost:8080/demo/ping findet sich
eine Response mit verschiedenen Datumsformaten wieder.
Die Anwendung verwendet Spring-Boot bzw. das eingebaute Jackson für die
Serialisierung/Deserialisierung von Objekten.
Die nächsten Abschnitte gliedern sich in einen Server und einen Client Teil.
Hier ein Auszug aus dem Spring-Boot RestController:
@RestController
@RequestMapping("/demo")
public class DateTimeController {
@GetMapping("/ping")
public PingDateTime ping() {
PingDateTime pdt = new PingDateTime();
pdt.setDateTime(new Date());
return pdt;
}
}
Interessant ist die Klasse PingDateTime. Hier passiert die Magic
(Für die Magic ist Jackson verantwortlich).
Mit der Annotation @JsonFormat in der Klasse DateTimeJson wird der Serialisierungsprozess gesteuert.
Out-of-the-box funktioniert die Annotation nur mit den Java Datentypen java.util.Date
und java.time.LocalDate bzw. java.time.LocalDateTime. Für den Joda org.joda.time.DateTime
Datentyp gibt es auf GitHub eine
Extension für Jackson.
Fehlt die Annotation, versucht der Serialisierer Jackson
eine Objekt-Dekonstruktion per Reflection. Im Falle von java.util.Date werden
die Millisekunden (Unix-Timestamp) zurückgeliefert. In der Spring-Boot Anwendung
wird dateTimeMillies formatiert ausgegeben trotz fehlender @JsonFormat Angabe.
Das Joda DateTime Objekt
erfährt bei der Serialisierung eine detailreiche Dekonstruktion.
Als Beispiel für Zeitzonen habe ich einmal 'Europe/Berlin' und 'UTC' gewählt.
"UTC" ist die sogenannte Weltzeit (Coordinated Universal Time). Diese definiert
keine Zeitzonen und gilt einheitlich auf der ganzen Welt. 'UTC' ist im strengen
Sinne keine Zeitzone. Die Parameterbezeichnung 'timezone' für den Typ 'UTC' ist
also nicht ganz korrekt.
Das Datumsangaben ohne Zeitzonen keine gute Idee sind, ist auch der Grund
warum java.util.Date durch java.time.LocalDateTime ersetzt werden sollte.
public class DateTimeJson {
@JsonFormat(
shape = JsonFormat.Shape.STRING,
pattern = "dd.MM.yyyy HH:mm",
locale = "de_DE",
timezone = "Europe/Berlin")
private Date dateTimeBerlin;
@JsonFormat(
shape = JsonFormat.Shape.STRING,
pattern = "dd.MM.yyyy HH:mm",
locale = "de_DE", timezone = "UTC")
private Date dateTimeUTC;
private DateTime jodaDateTime;
private Date dateTimeMillies;
@JsonFormat(
shape = JsonFormat.Shape.STRING,
pattern = "dd.MM.yyyy HH:mm",
locale = "de_DE", timezone = "UTC")
private LocalDateTime localDateTimeUTC;
@JsonFormat(
shape = JsonFormat.Shape.STRING,
pattern = "dd.MM.yyyy HH:mm",
locale = "de_DE",
timezone = "Europe/Berlin")
private LocalDateTime localDateTimeBerlin;
private LocalDateTime localDateTime;
// getter and setters...
}
In Projektverzeichnis findet sich eine Datei rest.http. Wer VisualCode mit dem
Rest-Plugin
verwendet, kann sich mit Hilfe dieser Datei die Response bequem im Editor anschauen.
Ebenfalls empfehlenswert ist das Tool httpie. Mit dem
Kommandozeilenaufruf
http http://localhost:8080/demo/ping erhält man eine nett formatierte Ausgabe
der Response:
HTTP/1.1 200
Content-Type: application/json;charset=UTF-8
Date: Fri, 11 Oct 2019 14:51:00 GMT
Transfer-Encoding: chunked
{
"dateTimeBerlin": "11.10.2019 16:51",
"dateTimeMillies": "2019-10-11T14:51:00.072+0000",
"dateTimeUTC": "11.10.2019 14:51",
"jodaDateTime": {
"afterNow": false,
"beforeNow": true,
"centuryOfEra": 20,
"chronology": {
"zone": {
"fixed": false,
"id": "Europe/Berlin",
"uncachedZone": {
"cachable": true,
"fixed": false,
"id": "Europe/Berlin"
}
}
},
"dayOfMonth": 11,
"dayOfWeek": 5,
"dayOfYear": 284,
"equalNow": false,
"era": 1,
"hourOfDay": 16,
"millis": 1570805460072,
"millisOfDay": 60660072,
"millisOfSecond": 72,
"minuteOfDay": 1011,
"minuteOfHour": 51,
"monthOfYear": 10,
"secondOfDay": 60660,
"secondOfMinute": 0,
"weekOfWeekyear": 41,
"weekyear": 2019,
"year": 2019,
"yearOfCentury": 19,
"yearOfEra": 2019,
"zone": {
"fixed": false,
"id": "Europe/Berlin",
"uncachedZone": {
"cachable": true,
"fixed": false,
"id": "Europe/Berlin"
}
}
},
"localDateTime": "2019-10-11T14:51:00.072",
"localDateTimeBerlin": "11.10.2019 16:51",
"localDateTimeUTC": "11.10.2019 14:51"
}
Mit curl würde das natürlich auch funktionieren.
{{tippModel.round.dateTime | date: 'dd.MM.yyyy HH:mm': '+0000'}}
Referenzen:
- Baeldung Spring Boot JSON Dates
- Internationaler Standard ISO 8601 für Datumsformate und Zeitangaben.
- Unix Zeitstempel Also die Zeit in Millisekunden seit dem 01.01.1970. Das funktioniert bis zum 19.01.2038. Also bereits in weniger als 20 Jahren werden wir einige Probleme bekommen.
- Unterschied von UTC zu GMT
- Javascript und das Date Objekt:
by Andre Winkler 2021, Hamburg