Technik

ISO 8601 in der Praxis, das Format das alle in Software nutzen sollten

Warum 2026-04-29T14:30:00Z besser ist als 29.04.2026 14:30, was die Z-, Offset- und Local-Varianten unterscheidet, und welche Stolperfallen auch erfahrene Entwickler treffen.

8 Min. Lesezeit Zuletzt geprüft:

Wer in einer Datenbank 29.04.2026 oder 4/29/26 stehen sieht, weiß zwei Dinge nicht: ist das April oder September, und in welcher Zeitzone. Die ISO 8601 löst beide Probleme mit einer eindeutigen, sortierbaren, sprachunabhängigen Notation. Sie ist der internationale Standard seit 1988, aber es gibt drei Varianten und mindestens fünf Stolperfallen, an denen erfahrene Entwickler regelmäßig scheitern.

Die Grundform

Eine vollständige ISO-8601-Datums-Zeit-Angabe sieht so aus:

2026-04-29T14:30:00Z

Aufgeschlüsselt: 2026-04-29 ist das Datum (Jahr-Monat-Tag, immer mit vier Ziffern Jahr und führenden Nullen). T ist der Trenner zwischen Datum und Zeit, kein Leerzeichen, weil ein Leerzeichen oft zu Parsing-Problemen führt. 14:30:00 ist die Zeit (Stunde:Minute:Sekunde, immer 24-Stunden, immer mit führenden Nullen). Z am Ende ist die Zeitzone-Angabe und steht für „Zulu Time", also UTC+0.

Diese Form hat drei Eigenschaften, die kein anderes Datumsformat kombiniert. Sie ist eindeutig (kein April-vs-September-Problem), sie ist alphabetisch sortierbar (was lexikographisch sortiert, ist auch zeitlich sortiert), und sie ist sprachunabhängig (keine Lokalisierung wie „Mar" vs. „Mär").

Die drei Zeitzonen-Varianten

ISO 8601 erlaubt drei Wege, die Zeitzone anzugeben. Welche du wählst, hängt von der Anwendung ab.

UTC mit Z. Das Z am Ende heißt explizit UTC+0. Beispiel: 2026-04-29T14:30:00Z. Standard für Server-Logs, API-Antworten und alles, was lokal-unspezifisch sein soll. Eindeutig, kompakt, in jedem Parser unterstützt.

Mit Offset. Statt Z folgt ein Offset wie +01:00, -08:30 oder +00:00. Beispiel: 2026-04-29T15:30:00+01:00 ist dieselbe Zeit wie 2026-04-29T14:30:00Z, nur lokal in Berlin Winterzeit dargestellt. Für User-facing Zeitangaben oft besser lesbar, weil der lokale Bezug erhalten bleibt.

Ohne Zeitzone (Local). Nur das Datum-Zeit-Format ohne Z oder Offset. Beispiel: 2026-04-29T14:30:00. Diese Form bedeutet „lokale Zeit irgendwo, aber wo, wird nicht spezifiziert". Sehr riskant, fast immer ein Bug. Verwendung sollte vermieden werden, außer in geschlossenen Single-Timezone-Systemen.

Die fünf häufigsten Bugs

Auch erfahrene Entwickler stolpern an diesen Stellen.

Bug 1: Local-Zeit ohne Zeitzone speichern. Eine User-Eingabe „14:30" wird als lokale Zeit gespeichert, beim Anzeigen wird sie wieder als lokale Zeit interpretiert. In einer Single-User-Single-Timezone-App funktioniert das. Sobald derselbe Datensatz in einer anderen Zeitzone gelesen wird (Server-Migration, internationale User, Backup-Restore), zeigt er die falsche Zeit. Lösung: Alle Zeiten in UTC speichern, nur an der UI in lokale Zeit konvertieren.

Bug 2: Datum ohne Zeit als „Tagesbeginn UTC" interpretieren. Wenn ein User das Datum „2026-04-29" in einem Berlin-Browser eingibt, denkt er „der 29. April in Berlin". Wenn die Software das als „2026-04-29T00:00:00Z" interpretiert, ist das tatsächlich der 29. April 2:00 Uhr Berlin-Zeit (Sommerzeit), nicht der Beginn des 29. April in Berlin. Lösung: Bei Datums-only-Eingaben explizit fragen oder als „date-local" speichern, nicht als Timestamp.

Bug 3: Ländercode-Datums-Konfusion. US-Format ist MM/DD/YYYY, deutsches Format DD.MM.YYYY. Bei der Eingabe „04/05/2026" weiß keine Software ohne Kontext, ob 4. Mai oder 5. April gemeint ist. Lösung: ISO 8601 (2026-04-05 oder 2026-05-04) als Eingabeformat erzwingen oder das User-Locale eindeutig signalisieren.

Bug 4: 24-Stunden vs. 12-Stunden bei Speicherung. Niemand sollte „2:30 PM" in die Datenbank schreiben. ISO 8601 ist immer 24-Stunden, intern. UI-seitig kann je nach Locale auch AM/PM angezeigt werden, aber die Speicherung ist 14:30:00.

Bug 5: Schaltsekunden ignorieren. Etwa zweimal pro Jahr fügt IERS eine Schaltsekunde ein, die letzte Sekunde eines Tages wird zu „23:59:60" statt „23:59:59". Die meisten Software-Plattformen behandeln das nicht korrekt, springen einfach zu „00:00:00" des Folgetags. Bei Hochfrequenz-Anwendungen (Trading, Telekommunikation) ist das relevant, im Alltag nicht. Java und Python ignorieren Schaltsekunden, JavaScript Date-Objekte auch.

Empfehlungen für Software-Praxis

Wer eine Anwendung entwickelt, die mit Zeit umgeht, sollte sich an ein paar Grundregeln halten.

Datenbank: alles in UTC mit Z. Eindeutig, sortierbar, transformations-resistent. PostgreSQL hat einen Type TIMESTAMPTZ, der genau das macht. MySQL DATETIME ist riskant, besser TIMESTAMP. SQLite hat keinen nativen Typ, ISO-Strings sind Standard.

API-Antwort: ISO 8601 mit Z, Frontend konvertiert. Server schickt 2026-04-29T14:30:00Z, Frontend zeigt das je nach User-Locale lokal an. JavaScript: new Date(iso).toLocaleString('de-DE', { timeZone: 'Europe/Berlin' }).

Eingabe-Felder: HTML5 datetime-local mit expliziter Zeitzone-Anzeige. Der HTML5-Type datetime-local liefert keine Zeitzone, das Frontend muss sie ergänzen, idealerweise mit der Browser-Zeitzone (Intl.DateTimeFormat().resolvedOptions().timeZone) und sichtbarem Zeitzone-Label am Eingabefeld.

Logging: ISO 8601 mit Z, immer. Logs werden oft über Zeitzonen hinweg ausgewertet. Nichts verwirrt mehr als ein Log-Eintrag in lokaler Zeit ohne Zeitzone-Angabe. Pythons logging kann ISO-Format produzieren, JavaScripts console.log(new Date().toISOString()) ebenso.

Quellen

  • ISO: ISO 8601:2019 Date and Time Format
  • RFC 3339: Date and Time on the Internet (Standard Track Subset von ISO 8601)
  • IERS: Bulletin C, Schaltsekunden-Ankündigungen
  • MDN Web Docs: Date.toISOString()

Häufige Fragen

Was ist der Unterschied zwischen ISO 8601 und RFC 3339?

RFC 3339 ist ein engerer Subset von ISO 8601, optimiert für Internet-Protokolle. RFC 3339 verlangt das Z oder einen Offset, ISO 8601 erlaubt auch Local-Zeit ohne Zone. Für APIs immer RFC 3339 nutzen.

Soll ich Datum und Zeit getrennt oder zusammen speichern?

Wenn die Zeit relevant ist, immer zusammen als Timestamp. Trennung führt zu Synchronisations-Bugs. Wenn nur das Datum relevant ist (Geburtstag, Vertragslaufzeit), als Date-only ohne Zeitkomponente speichern.

Was tun mit Zeit-Eingaben aus alten Systemen ohne Zeitzone?

Beim Import dokumentieren, in welcher Zeitzone die Daten ursprünglich vorlagen, und einen einmaligen Convert nach UTC durchführen. Beispiel: Alle Datensätze aus dem alten DE-System sind als Europe/Berlin lokal interpretiert, beim Import in die neue UTC-Datenbank wird konvertiert.

Welche Programmiersprache hat die beste Zeitzonen-Unterstützung?

Java mit dem java.time-Package (seit Java 8) ist heute Goldstandard. Python mit pytz oder dem neueren zoneinfo (Python 3.9+) ist solide. JavaScript Date-Objekt ist eingeschränkt, mit Bibliotheken wie luxon oder date-fns aber arbeitsfähig.

Warum nutzen viele APIs Unix-Timestamps statt ISO 8601?

Unix-Timestamp (Sekunden seit 1970) ist platzsparend (eine Zahl statt 20 Zeichen) und über alle Sprachen gleich parsbar. Nachteil: nicht menschen-lesbar in Logs, kein eingebauter Zeitzone-Hinweis, Year-2038-Problem für 32-Bit-Systeme.