Unix-Timestamp-Konverter: Epochs, Zeitzonen und 2038

9 min20. Mai 2026

Was ein Unix-Timestamp-Konverter macht (und warum du einen brauchst)

Ein Unix-Timestamp-Konverter übersetzt zwischen menschenlesbaren Daten und der Anzahl der Sekunden seit dem 1. Januar 1970 00:00:00 UTC (dem "Unix-Epoch"). Gerade jetzt, während ich das schreibe, ist der Timestamp ungefähr 1.780.000.000. Diese Zahl erhöht sich jede Sekunde um 1, wird nie zurückgesetzt und kümmert sich nicht um Zeitzonen, Sommerzeit oder Schaltjahre. Es ist die einfachste mögliche Art, einen Moment in der Zeit darzustellen.

Warum brauchen Entwickler einen Konverter? Weil Menschen in "4. Juni 2026 um 15:30 Uhr" denken und Computer in 1780646400. Jede API, Datenbank und Log-Datei verwendet das eine oder andere Format (oder beide). Von Hand zwischen ihnen zu konvertieren erfordert Wissen über den Zeitzonen-Offset, ob Sommerzeit aktiv ist und wie viele Sekunden jeder Monat hat. Oder du verwendest einfach ein Konverter-Tool und bekommst die Antwort in Millisekunden.

Der Unix-Epoch (1. Januar 1970) wurde willkürlich von den Schöpfern von Unix bei Bell Labs gewählt. Er hat keine astronomische oder historische Bedeutung. Andere Systeme verwenden andere Epochs: Windows FILETIME zählt 100-Nanosekunden-Intervalle seit dem 1. Januar 1601. macOS Cocoa zählt Sekunden seit dem 1. Januar 2001. GPS-Zeit zählt Wochen und Sekunden seit dem 6. Januar 1980. Zwischen diesen zu konvertieren erfordert Kenntnis sowohl des Epochs als auch der Einheit.

Sekunden vs Millisekunden (die #1 Bug-Quelle)

Unix-Timestamps zählen traditionell Sekunden. JavaScripts Date.now() gibt Millisekunden zurück. Javas System.currentTimeMillis() gibt Millisekunden zurück. Pythons time.time() gibt Sekunden zurück (als Float). Diese Inkonsistenz verursacht ständig Bugs. Wenn du einen Timestamp von 1780646400 siehst, sind es Sekunden (Juni 2026). Wenn du 1780646400000 siehst, sind es Millisekunden (der gleiche Moment). Wenn du versehentlich Millisekunden als Sekunden behandelst, bekommst du ein Datum im Jahr 58.400.

Der schnelle Check: Wenn die Zahl 10 Stellen hat, sind es Sekunden (gültig von 2001 bis 2286). Wenn sie 13 Stellen hat, sind es Millisekunden (gültig von 2001 bis 2286). Wenn sie 16 Stellen hat, sind es Mikrosekunden (Pythons datetime.timestamp() mit Mikrosekunden-Präzision). Unser timestamp-converter Tool erkennt die Einheit automatisch anhand der Stellenanzahl.

Meine Regel: Speichere Timestamps immer in Millisekunden (oder im ISO-8601-String-Format). Millisekunden geben dir Sub-Sekunden-Präzision ohne die Gleitkomma-Probleme von Bruchsekunden. Jede moderne Sprache kann 64-Bit-Integer verarbeiten, also sind die Speicherkosten gleich. Wenn du mit APIs interagierst, die Sekunden verwenden, multipliziere/dividiere an der Grenze durch 1000 — lass gemischte Einheiten sich nicht durch deinen Code ausbreiten.

Ein Bug, den ich 2021 hatte: Ein Zahlungssystem speicherte "created_at" in Sekunden, aber die Webhook-Verifizierung prüfte "Timestamp ist innerhalb von 5 Minuten von jetzt" mit Millisekunden. Die Prüfung schlug immer fehl, weil die Differenz 1.780.000.000.000 Millisekunden war (der Timestamp in Sekunden, interpretiert als Millisekunden = Jahr 58.400) minus die aktuelle Zeit. Es dauerte 3 Stunden, es zu finden, weil die Fehlermeldung nur "timestamp expired" sagte.

Zeitzonen-Bugs, die jeden Entwickler treffen

Der häufigste Zeitzonen-Bug: Lokalzeit ohne Zeitzonen-Information speichern. Wenn deine Datenbank "2026-06-04 15:30:00" hat — ist das UTC? Mitteleuropäische Zeit? Die Zeitzone des Servers? Wenn der Server in eine andere Zeitzone umzieht (oder du in eine andere Cloud-Region migrierst), verschieben sich alle deine Timestamps. Speichere immer UTC und konvertiere nur für die Anzeige in Lokalzeit.

Sommerzeit erzeugt unmögliche und mehrdeutige Zeiten. Am 27. Oktober 2024 um 3:00 Uhr MEZ wurden die Uhren auf 2:00 Uhr zurückgestellt. Die Zeit "2:30 Uhr" passierte zweimal. Am 31. März 2024 um 2:00 Uhr sprangen die Uhren auf 3:00 Uhr. Die Zeit "2:30 Uhr" existierte nie. Wenn dein Planungssystem ein Event um 2:30 Uhr an einem Vorstellungstag erstellt, was passiert? Die meisten Systeme verschieben es stillschweigend auf 3:30 Uhr. Manche stürzen ab.

Der "Tagesgrenze"-Bug: "Heutige Bestellungen" bedeutet verschiedene Dinge in verschiedenen Zeitzonen. Wenn dein Server in UTC ist und ein Nutzer in Deutschland um 23:30 Uhr MEZ bestellt (22:30 UTC), erscheint es im Bericht von "heute" — aber für den Nutzer war es noch "heute". Lösung: Filtere immer nach den lokalen Tagesgrenzen des Nutzers, konvertiert zu UTC. Speichere die Zeitzone des Nutzers (IANA-Format wie "Europe/Berlin", nicht UTC-Offsets, die Sommerzeit nicht berücksichtigen).

JavaScripts Date-Objekt ist zeitzonen-bewusst, aber verwirrend. new Date("2026-06-04") wird als UTC-Mitternacht geparst, aber new Date("2026-06-04T00:00:00") wird als Lokalzeit geparst. new Date(2026, 5, 4) verwendet Lokalzeit (und Monate sind 0-indiziert, also 5 = Juni). Diese Inkonsistenz hat mehr Bugs verursacht als jede andere JavaScript-API. Verwende die Temporal API (Stage 3, verfügbar in Polyfills) oder Bibliotheken wie date-fns mit explizitem Zeitzonen-Handling.

// The timezone trap in JavaScript
new Date("2026-06-04");           // UTC midnight
new Date("2026-06-04T00:00:00"); // LOCAL midnight (different!)
new Date(2026, 5, 4);            // LOCAL midnight, month 5 = June

// Safe approach: always be explicit about timezone
new Date("2026-06-04T00:00:00Z");      // UTC (the Z matters)
new Date("2026-06-04T00:00:00+02:00"); // MESZ (Berlin summer)

// Converting timestamp to readable date
const ts = 1780646400;
new Date(ts * 1000).toISOString();     // "2026-06-04T12:00:00.000Z"
new Date(ts * 1000).toLocaleString("de-DE", {
  timeZone: "Europe/Berlin"
}); // "4.6.2026, 14:00:00"

Das Jahr-2038-Problem (es ist real)

Ein vorzeichenbehafteter 32-Bit-Integer kann Werte bis 2.147.483.647 halten. So viele Sekunden nach dem Unix-Epoch ist der 19. Januar 2038 um 03:14:07 UTC. Nach diesem Moment laufen 32-Bit-Timestamps zu negativen Zahlen über und springen zurück zum 13. Dezember 1901. Das ist das Y2K-Problem für Unix-Systeme, und es ist 12 Jahre entfernt.

Was betroffen ist: Eingebettete Systeme (IoT-Geräte, Bordcomputer, Industriesteuerungen), ältere Datenbanken mit 32-Bit-Timestamp-Spalten, C-Programme, die time_t als 32-Bit-Int verwenden, und Dateiformate, die 32-Bit-Timestamps speichern (ext3-Dateisystem, manche ZIP-Implementierungen). Der Linux-Kernel wechselte zu 64-Bit time_t für 32-Bit-Architekturen in Kernel 5.6 (2020), aber User-Space-Programme, die gegen ältere Bibliotheken kompiliert wurden, verwenden möglicherweise noch 32-Bit-Zeit.

Was NICHT betroffen ist: Jedes 64-Bit-System (alle modernen Server, Desktops und Telefone), JavaScript (verwendet 64-Bit-Floats für Timestamps), Python (Integer mit beliebiger Präzision), Java (long ist 64-Bit), PostgreSQL (Timestamp-Typ ist 64-Bit). Wenn du 2026 eine Webanwendung schreibst, bist du fast sicher in Ordnung. Das Risiko liegt bei eingebetteten Systemen und Legacy-Code, der vor 2038 nicht aktualisiert wird.

Wenn du Legacy-Systeme wartest: Prüfe deinen Timestamp-Speicher. MySQLs TIMESTAMP-Typ war 32-Bit bis MySQL 8.0.28 (2022) — ältere Versionen werden 2038 überlaufen. SQLite speichert Timestamps als Text oder 64-Bit-Integer (sicher). Prüfe jeden C/C++-Code, der time_t verwendet — auf 32-Bit-Plattformen kann es noch 32 Bits sein. Die Lösung ist normalerweise Neukompilierung mit _TIME_BITS=64 oder Migration auf 64-Bit-Plattformen.

Timestamps in Datenbanken speichern

PostgreSQL: Verwende TIMESTAMPTZ (timestamp with time zone). Trotz des Namens speichert es keine Zeitzone — es speichert UTC und konvertiert bei Ein-/Ausgabe zur/von der Session-Zeitzone. Einfaches TIMESTAMP (ohne Zeitzone) speichert, was du ihm gibst, ohne Konvertierung, was zu Mehrdeutigkeit führt. Verwende immer TIMESTAMPTZ.

MySQL: TIMESTAMP speichert UTC (4 Bytes, Bereich 1970-2038 in älteren Versionen, erweitert in 8.0.28+). DATETIME speichert den literalen Wert ohne Zeitzonen-Konvertierung (8 Bytes, Bereich 1000-9999). Verwende TIMESTAMP für "wann ist das passiert" (konvertiert automatisch zu UTC) und DATETIME für "geplant für genau dieses Datum/diese Uhrzeit unabhängig von der Zeitzone" (wie ein Geburtstag oder ein Meeting in einer bestimmten Zeitzone).

MongoDB: Der Date-Typ speichert Millisekunden seit Epoch als 64-Bit-Integer. Intern ist es immer UTC. Der ISODate()-Shell-Helper ist nur syntaktischer Zucker für new Date(). Speichere alle Daten als Date-Objekte, nicht als Strings. String-Daten können nicht effizient indiziert werden und Vergleichsoperatoren funktionieren nicht korrekt über Zeitzonen hinweg.

Allgemeiner Rat: Speichere UTC-Timestamps, speichere die Zeitzone des Nutzers separat (als IANA-Zeitzonen-String wie "Europe/Berlin"), und berechne die lokale Anzeigezeit in der Anwendungsschicht. Speichere nie vorformatierte Datums-Strings — du verlierst die Möglichkeit, für verschiedene Locales neu zu formatieren oder neu zu berechnen, wenn sich Zeitzonen-Regeln ändern (was öfter passiert als du denkst — Regierungen ändern Sommerzeit-Regeln regelmäßig).

Schaltsekunden (der Randfall, der Dinge kaputt macht)

Die Erdrotation verlangsamt sich, also fügt UTC gelegentlich eine "Schaltsekunde" hinzu, um mit der astronomischen Zeit synchron zu bleiben. Wenn das passiert, existiert die Zeit 23:59:60 für eine Sekunde vor Mitternacht. Unix-Timestamps handhaben das, indem sie entweder eine Sekunde wiederholen (die Uhr zeigt den gleichen Timestamp zweimal) oder die Schaltsekunde über einen längeren Zeitraum "verschmieren" (Googles Ansatz: über 24 Stunden verteilen, sodass jede Sekunde etwas länger ist).

In der Praxis haben Schaltsekunden echte Ausfälle verursacht. Reddit war 30 Minuten down während der Schaltsekunde im Juni 2012, weil das Clock-Handling des Linux-Kernels einen Bug hatte, der hohe CPU-Auslastung verursachte. Cloudflare hatte einen kurzen Ausfall im Januar 2017, als ihre RRDNS-Software eine negative Zeitdauer während der Schaltsekunde berechnete. Diese Bugs sind selten, aber spektakulär.

Die gute Nachricht: Das Internationale Büro für Maß und Gewicht (BIPM) stimmte 2022 dafür, Schaltsekunden bis 2035 abzuschaffen. Bis dahin gibt es 27 akkumulierte Schaltsekunden seit 1972. Die meisten modernen Systeme verwenden NTP (Network Time Protocol), das Schaltsekunden transparent handhabt. Wenn du ein System baust, das Sub-Sekunden-Genauigkeit über Schaltsekunden-Grenzen braucht (Finanzhandel, wissenschaftliche Instrumente), verwende TAI (Internationale Atomzeit), die keine Schaltsekunden hat.

Für die meisten Entwickler: Ignoriere Schaltsekunden. Die Standardbibliothek deiner Sprache handhabt sie (oder tut so, als gäbe es sie nicht, was für 99,99% der Anwendungen in Ordnung ist). Versuche nicht, sie manuell zu berücksichtigen. Das einzige Mal, dass du es bemerkst, ist wenn du exakte Dauern über eine Schaltsekunden-Grenze berechnest und 61 Sekunden in einer "Minute" bekommst — was technisch korrekt ist.

Praktische Muster für die Arbeit mit Timestamps

Muster 1: API-Antworten. Gib ISO-8601-Strings mit Zeitzonen-Offset zurück: "2026-06-04T15:30:00+02:00" oder UTC mit Z-Suffix: "2026-06-04T13:30:00Z". Gib keine rohen Unix-Timestamps in nutzerorientierten APIs zurück — sie sind ohne Konverter unlesbar. Interne Service-zu-Service-APIs können Millisekunden-Timestamps für Effizienz verwenden.

Muster 2: Zukünftige Events planen. Speichere die beabsichtigte Lokalzeit UND die Zeitzone: {time: "2026-12-25T09:00:00", timezone: "Europe/Berlin"}. Konvertiere nicht vorab zu UTC, weil wenn sich die Zeitzonen-Regeln ändern (Regierung verschiebt Sommerzeit-Daten), deine gespeicherte UTC-Zeit falsch wird. Konvertiere zum Ausführungszeitpunkt zu UTC mit der neuesten Zeitzonen-Datenbank.

Muster 3: Audit-Logs und Event Sourcing. Verwende monotone Timestamps (nicht Wanduhr-Zeit) zum Ordnen von Events innerhalb eines einzelnen Prozesses. Wanduhren können rückwärts springen (NTP-Korrekturen, VM-Migrationen, Schaltsekunden). Für maschinenübergreifende Ordnung verwende logische Uhren (Lamport-Timestamps, Vektoruhren) oder synchronisierte Timestamps mit begrenztem Fehler (Google Spanners TrueTime, AWS Time Sync).

Muster 4: Altersberechnungen. Subtrahiere nicht Timestamps und dividiere durch Sekunden-pro-Jahr (365,25 × 86400). Das versagt bei Schaltjahren, Sommerzeit-Übergängen und Zeitzonen-Unterschieden. Verwende eine richtige Datumsbibliothek, die Kalender-Differenzen berechnet: differenceInYears() von date-fns, Pythons relativedelta, oder unser age-calculator Tool, das all diese Randfälle korrekt behandelt.