Zeitzonen in Kotlin: Wie man mit der Zeit nicht verrückt wird

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 eine Qual ist (und wie Kotlin sie heilt)

\n\n

Wenn Sie jemals eine Anwendung geschrieben haben, die Benutzer aus verschiedenen Zeitzonen bedient, kennen Sie diesen Schmerz. Eine Anfrage kommt mit einem Timestamp, in der Datenbank liegt UTC, ein Benutzer in New York beschwert sich, dass die Benachrichtigung um 3 Uhr nachts kam, während es in der Datenbank 8 Uhr morgens war. Kommt Ihnen das bekannt vor?

\n\n

Die Arbeit mit Zeitzonen ist der Bereich der Programmierung, in dem sich scheinbare Einfachheit in Dutzende von Bugs verwandelt. Aber Kotlin, das die besten Praktiken von Java geerbt hat, gibt uns ein mächtiges Arsenal, um mit dem Chaos umzugehen. In diesem Artikel werden wir untersuchen, wie man richtig mit Zeitzonen in Kotlin arbeitet, typische Fehler vermeidet und Code schreibt, der bei der Umstellung auf Sommerzeit nicht kaputt geht.

\n\n

Kurzer Exkurs: Was ist eine Zeitzone?

\n\n

Bevor wir in den Code eintauchen, lassen Sie uns die Begriffe klären. Eine Zeitzone (time zone) ist nicht nur eine Verschiebung relativ zur UTC. Sie ist auch eine Reihe von Regeln für die Umstellung auf Sommer-/Winterzeit (DST). Zum Beispiel ist Europe/Moscow nicht nur +3 Stunden, sondern auch historische Änderungen (2014 hat Russland aufgehört, die Uhren umzustellen).

\n\n

In der Java/Kotlin-Welt sind zwei Schlüsselkonzepte dafür verantwortlich:

\n\n
    \n
  • ZoneId – die Kennung der Zeitzone (z. B. "America/New_York"). Enthält die gesamte DST-Geschichte.
  • \n
  • ZoneOffset – nur die Verschiebung (z. B. +05:00). Ohne Umstellungsregeln.
  • \n
\n\n

Der Unterschied ist entscheidend: Wenn Sie ZoneOffset anstelle von ZoneId verwenden, wird Ihr Code am Tag der Zeitumstellung kaputtgehen. Merken Sie sich das.

\n\n

Basisklassen von java.time in Kotlin

\n\n

Kotlin unterstützt das Paket java.time (Java 8+) vollständig. Wenn Sie für Android entwickeln, vergessen Sie nicht, desugaring hinzuzufügen oder ThreeTenABP zu verwenden. Für serverseitiges Kotlin gibt es keine Probleme.

\n\n

Instant – ein Moment in der Zeit

\n\n

Instant ist ein absoluter Moment auf der Zeitachse. Er ist nicht an eine Zeitzone gebunden. Genau das sollte in der Datenbank gespeichert werden.

\n\n
import java.time.Instant\n\nfun main() {\n    val now = Instant.now()\n    println(now) // 2025-03-15T10:30:00.123Z\n}
\n\n

Beachten Sie den Buchstaben Z am Ende – das ist Zulu-Zeit, also UTC. Speichern Sie alles in UTC – das ist die goldene Regel.

\n\n

ZonedDateTime – Zeit mit Zeitzone

\n\n

Wenn Sie dem Benutzer die Zeit anzeigen müssen, verwenden Sie ZonedDateTime. Es speichert Datum, Uhrzeit, Verschiebung und die Zonenkennung.

\n\n
import java.time.ZonedDateTime\nimport java.time.ZoneId\n\nfun main() {\n    val moscowTime = ZonedDateTime.now(ZoneId.of("Europe/Moscow"))\n    println(moscowTime) // 2025-03-15T13:30:00.123+03:00[Europe/Moscow]\n}
\n\n

Sehen Sie die eckigen Klammern? Das ist genau ZoneId, das es dem System ermöglicht, DST korrekt zu verarbeiten.

\n\n

OffsetDateTime – Zeit mit Verschiebung

\n\n

Wenn Sie keine Informationen über die Zone benötigen, sondern nur die Verschiebung, verwenden Sie OffsetDateTime. Es ist leichter und schneller.

\n\n
import java.time.OffsetDateTime\nimport java.time.ZoneOffset\n\nfun main() {\n    val offsetTime = OffsetDateTime.now(ZoneOffset.ofHours(5))\n    println(offsetTime) // 2025-03-15T15:30:00.123+05:00\n}
\n\n

Aber denken Sie daran: Wenn Sie OffsetDateTime für New York speichern und die USA dann auf Sommerzeit umstellt, wird Ihre Verschiebung veraltet sein.

\n\n

Konvertierung zwischen Zeitzonen in Kotlin

\n\n

Die häufigste Aufgabe ist es, die Zeit aus der Datenbank (UTC) zu nehmen und sie in der Zeitzone des Benutzers anzuzeigen. Lassen Sie uns untersuchen, wie man das richtig macht.

\n\n

Von UTC in die lokale Zone

\n\n
import java.time.Instant\nimport java.time.ZoneId\nimport java.time.ZonedDateTime\n\nfun convertUtcToLocal(utcInstant: Instant, targetZone: String): ZonedDateTime {\n    return utcInstant.atZone(ZoneId.of(targetZone))\n}\n\nfun main() {\n    val utcNow =                

Blogs

Buchempfehlungen