Python-Kurs / Datum, Zeitspannen und Zeitzonen mit datetime und zoneinfo
Für einen Kalendertag verwenden Sie date; für Datum und Uhrzeit verwenden Sie datetime. Soll ein Wert einen eindeutigen Zeitpunkt bezeichnen, benötigen Sie außerdem eine bekannte Zeitzone: Mit zoneinfo lässt sich dieser Zeitpunkt beispielsweise von UTC in die Ortszeit von Seoul umrechnen.
Kalendertag, Dauer und Zeitpunkt unterscheiden
Ein Rechnungsdatum wie der 17. Oktober ist zunächst ein Kalendertag. date speichert Jahr, Monat und Tag ohne Uhrzeit. datetime ergänzt Stunden, Minuten und weitere Zeitanteile. timedelta beschreibt eine Zeitspanne, beispielsweise sieben Tage. Diese drei Aufgaben sollten Sie schon beim Entwurf eines Eingabeformulars auseinanderhalten.
Ein naiver datetime-Wert enthält keine verwendbare Zeitzoneninformation. Ein aware, also zeitzonenbewusster Wert, besitzt eine Zeitzoneninterpretation mit einem bestimmbaren UTC-Offset. UTC steht für Coordinated Universal Time, die koordinierte Weltzeit. 09:00 Uhr in Seoul und 09:00 Uhr in UTC bezeichnen nicht denselben Zeitpunkt.
Mit date.fromisoformat("2026-10-17") lesen Sie die hier verwendete ISO-Datumsdarstellung ein. Ein ungültiger Tag wie 2026-02-30 löst ValueError aus; behandeln Sie dies als Eingabefehler. Eine Addition von 30 Tagen ist dagegen eine feste Tagesanzahl und kein allgemeiner Ersatz für „einen Kalendermonat später“. Für Monatsfristen müssen Sie zusätzlich festlegen, was etwa mit dem 31. Januar geschehen soll.
Einen UTC-Zeitpunkt in die Uhrzeit von Seoul umrechnen
Verwenden Sie Python 3.9 oder neuer und einen eigenen Übungsordner. Aktivieren Sie Ihre Projektumgebung und speichern Sie das folgende vollständige Programm als UTF-8-Datei dates.py. Falls die Zeitzonendaten fehlen, bereiten Sie die Umgebung wie im folgenden Abschnitt beschrieben vor. Starten Sie anschließend python dates.py; außerhalb einer virtuellen Umgebung kann unter macOS oder Ubuntu stattdessen python3 dates.py erforderlich sein.
from datetime import date, datetime, timedelta, timezone
from zoneinfo import ZoneInfo
day = date.fromisoformat("2026-10-17")
print(day + timedelta(days=7))
utc = datetime(2026, 10, 17, 0, 0, tzinfo=timezone.utc)
seoul = utc.astimezone(ZoneInfo("Asia/Seoul"))
print(utc.isoformat())
print(seoul.isoformat())
Die Ausgabe lautet:
2026-10-24
2026-10-17T00:00:00+00:00
2026-10-17T09:00:00+09:00
Die erste Zeile verschiebt nur das Kalenderdatum um sieben Tage. Die zweite Zeile beschreibt Mitternacht in UTC durch den Offset +00:00. astimezone() berechnet daraus für denselben Zeitpunkt 09:00 Uhr in Seoul mit dem Offset +09:00. Es vergehen bei dieser Umrechnung keine neun Stunden: Nur die Darstellung desselben Zeitpunkts ändert sich.
isoformat() liefert eine gut weiterzuverarbeitende Darstellung. Ein numerischer Offset in dieser Zeichenfolge enthält allerdings nicht den vollständigen Namen einer Region samt ihren Regeln. Wenn Ihre Anwendung diese Information später benötigt, bewahren Sie auch den Zeitzonenschlüssel auf.
Zeitzonendaten bereitstellen und replace richtig einordnen
ZoneInfo("Asia/Seoul") nutzt Regeln aus der IANA-Zeitzonendatenbank. Python sucht diese Daten im System oder im Paket tzdata. Besonders auf Windows fehlt häufig eine passende Systemdatenbank. Wenn ZoneInfoNotFoundError auftritt, installieren Sie mit python -m pip install tzdata die Daten in derselben virtuellen Umgebung, in der Sie das Programm ausführen. Ein Paket in einem anderen Interpreter behebt den Fehler nicht.
Die Datenquelle und die plattformübergreifende Abhängigkeit beschreibt die Python-Dokumentation zu den Datenquellen von zoneinfo. Verwalten Sie die Datenversion auch bei einer Bereitstellung; regionale Zeitregeln können sich ändern. Einen unbekannten Schlüssel sollten Sie außerdem auf Schreibfehler prüfen.
Speichern Sie für den direkten Vergleich die folgende zweite Datei als zones.py und starten Sie python zones.py in derselben Umgebung.
from datetime import datetime, timezone
from zoneinfo import ZoneInfo
utc = datetime(2026, 10, 17, 0, 0, tzinfo=timezone.utc)
print(utc.astimezone(ZoneInfo("Asia/Seoul")).isoformat())
print(utc.replace(tzinfo=ZoneInfo("Asia/Seoul")).isoformat())
try:
print(datetime(2026, 10, 17) - utc)
except TypeError:
print("naive and aware cannot be subtracted")
Erwartete Ausgabe:
2026-10-17T09:00:00+09:00
2026-10-17T00:00:00+09:00
naive and aware cannot be subtracted
Die erste Zeile ist eine echte Umrechnung. In der zweiten Zeile behält replace(tzinfo=...) die Uhrzeitfelder 00:00 bei und weist ihnen eine andere Interpretation zu. Damit entsteht hier ein anderer Zeitpunkt. Verwenden Sie replace nur, wenn Sie bewusst eine bekannte Interpretation zuweisen oder Felder ersetzen wollen; es ersetzt keine Zeitzonenumrechnung.
Die englische Meldung in der letzten Zeile wird vom Beispiel selbst ausgegeben, nachdem die Subtraktion einen TypeError ausgelöst hat. Ein naiver Wert liefert keine eindeutige Grundlage für den Vergleich mit dem UTC-Zeitpunkt. Ergänzen Sie deshalb nicht einfach UTC, nur damit die Ausnahme verschwindet: Zuerst muss die Herkunftszeitzone feststehen. Weitere Einzelheiten zu Objekten und Operationen stehen in der Referenz zu datetime.
Speicherung festlegen und Datumsgrenzen prüfen
Bei einer Zahlung mit konkretem Erfassungszeitpunkt können Sie eine einheitliche UTC-Darstellung speichern und für die Anzeige in die gewünschte Ortszeit umrechnen. Ein fachliches Ausgabedatum ohne Uhrzeit sollten Sie dagegen als Datum behandeln. Eine willkürlich ergänzte Mitternacht kann bei einer späteren Zeitzonenumrechnung auf einen anderen Kalendertag fallen und so die Bedeutung verändern.
- Ändern Sie in
dates.pydie Stunde des UTC-Werts von0auf23. Seoul muss dann2026-10-18T08:00:00+09:00anzeigen. Stellen Sie anschließend die Stunde wieder auf0. - Ersetzen Sie vorübergehend das eingelesene Datum durch
2026-02-30. Prüfen Sie denValueErrorund stellen Sie danach2026-10-17wieder her. Der Fehler tritt bereits beim Einlesen auf; spätere Ausgaben werden deshalb nicht erreicht. - Vergleichen Sie die beiden Zeitzonenoperationen in
zones.py: Nurastimezoneerhält den ursprünglichen UTC-Zeitpunkt. Begründen Sie anschließend, warum die letzte Subtraktion mit dem naiven Datum abgelehnt wird.
Für regelmäßige lokale Termine reicht eine feste Zahl von Stunden nicht immer aus. Bei einer Region mit Sommerzeit können sich die Abstände zwischen lokalen Uhrzeiten ändern. Legen Sie für solche Anwendungen fest, ob ein Kalendertermin in einer Region oder eine tatsächlich verstrichene Zeitspanne gemeint ist. Prüfen Sie diese Regel an den betroffenen Datumsgrenzen, bevor Sie daraus Fristen oder Berichte berechnen.




