Zeitzonen in Java: Wie man nicht den Verstand verliert und die Deadline nicht verpasst

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Warum Zeit in Java eine Qual ist (und wie man sie heilt)

\n

Jeder Entwickler, der sich schon einmal mit Aufgaben der Anwendungsglobalisierung beschäftigt hat, weiß: Die Arbeit mit Zeitzonen ist ein Minenfeld. Was könnte einfacher sein? Man nimmt ein Datum, konvertiert es in eine andere Zeitzone, und fertig. Aber nein. Alte APIs wie java.util.Date und java.util.Calendar hinterließen eine Menge Bugs, Verwirrung mit der Sommerzeit und graue Haare.

\n

Zum Glück hat sich mit der Veröffentlichung von Java 8 die Welt verändert. Das neue Paket java.time (JSR-310) brachte Ordnung und Klarheit. Heute werden wir uns ansehen, wie man in modernem Java korrekt mit Zeitzonen arbeitet, typische Fallstricke vermeidet und den Code lesbar und zuverlässig macht.

\n

Wenn Sie in Java programmieren und Ihre Anwendung mit Benutzern aus verschiedenen Ländern arbeitet, ist dieser Artikel für Sie. Los geht's!

\n\n

Einführung in die neue API: java.time

\n

Bevor wir in die Tiefe eintauchen, lassen Sie uns die wichtigsten Klassen verstehen. Es sind nicht viele, und jede ist für eine bestimmte Aufgabe zuständig.

\n\n

LocalDateTime — Zeit ohne Zonenbindung

\n

Diese Klasse speichert Datum und Uhrzeit, berücksichtigt aber keine Zeitzone. Sie eignet sich gut für die Aufzeichnung von Ereignissen, die am selben Ort stattfinden (z. B. Server-Logs).

\n
LocalDateTime local = LocalDateTime.now();\nSystem.out.println(local); // 2025-03-15T14:30:00.123
\n

Aber wenn Sie versuchen, diese Zeit an einen Benutzer in New York zu senden, während Ihr Server in Moskau steht, erhalten Sie Verwirrung. Daher sind für globale Systeme andere Werkzeuge erforderlich.

\n\n

ZonedDateTime — Zeit mit vollständigen Zoneninformationen

\n

Dies ist der „Goldstandard" für die Arbeit mit Zeitzonen in Java. Er speichert Datum, Uhrzeit und die Kennung der Zeitzone (ZoneId). Diese Klasse sollte verwendet werden, wenn Sie genau wissen möchten, in welcher Zone sich ein Ereignis befindet.

\n
ZonedDateTime nowInMoscow = ZonedDateTime.now(ZoneId.of("Europe/Moscow"));\nSystem.out.println(nowInMoscow); // 2025-03-15T14:30+03:00[Europe/Moscow]
\n\n

OffsetDateTime — Zeit mit Offset

\n

Ähnlich wie ZonedDateTime, speichert aber nur den Offset von UTC (z. B. +03:00), ohne den Regionsnamen. Nützlich für APIs, bei denen nur die Differenz zur Greenwich-Zeit wichtig ist.

\n\n

Instant — Zeitpunkt in UTC

\n

Maschinenlesbares Format. Instant ist ein Punkt auf der Zeitachse, immer in UTC. Ideal für die Speicherung in Datenbanken und den Austausch zwischen Diensten.

\n
Instant instant = Instant.now();\nSystem.out.println(instant); // 2025-03-15T11:30:00.123Z
\n\n

Wie man die Zeitzone richtig auswählt: ZoneId

\n

Verwenden Sie keine dreibuchstabigen Abkürzungen wie "PST" oder "CET" — sie sind mehrdeutig und berücksichtigen keine Sommerzeit. Verwenden Sie stattdessen die vollständigen Kennungen aus der IANA-Datenbank (Time Zone Database).

\n

Beispiele für korrekte ZoneId:

\n
    \n
  • "Europe/Moscow"
  • \n
  • "America/New_York"
  • \n
  • "Asia/Tokyo"
  • \n
  • "UTC"
  • \n
\n

Alle verfügbaren Zonen erhalten Sie so:

\n
Set<String> zoneIds = ZoneId.getAvailableZoneIds();\nzoneIds.stream().sorted().limit(10).forEach(System.out::println);
\n\n

Konvertierung zwischen Zeitzonen: Praktische Beispiele

\n

Die häufigste Aufgabe ist es, eine Zeit in einer Zone zu nehmen und sie einem Benutzer in einer anderen anzuzeigen. Das geht ganz einfach.

\n\n

Beispiel 1: Zeit von Moskau nach New York konvertieren

\n
ZonedDateTime moscowTime = ZonedDateTime.now(ZoneId.of("Europe/Moscow"));\nZonedDateTime newYorkTime = moscowTime.withZoneSameInstant(ZoneId.of("America/New_York"));\n\nSystem.out.println("Moskau: " + moscowTime);\nSystem.out.println("New York: " + newYorkTime);
\n

Beachten Sie die Methode withZoneSameInstant() — sie ändert nur die Zeitanzeige, während der physikalische Moment erhalten bleibt.

\n\n

Beispiel 2: Von UTC in die lokale Zeit des Benutzers

\n

Blogs

Buchempfehlungen