Das Jahr-2038-Problem (Y2K38) erklärt
Am 19. Januar 2038 um 03:14:07 UTC läuft der Unix-Timestamp 2.147.483.647 — der Maximalwert einer vorzeichenbehafteten 32-Bit-Ganzzahl — über und springt auf ein Datum im Jahr 1901. Hier erfährst du, was das bedeutet, welche Systeme betroffen sind, wie die 64-Bit-time_t-Lösung funktioniert und wie du deinen eigenen Code testest.
Der Überlauf in einer Zeile
Eine vorzeichenbehaftete 32-Bit-Ganzzahl reicht maximal bis 2.147.483.647. Als Unix-Sekunden gespeichert ist dieser Wert der 19.01.2038 03:14:07 UTC — und eine Sekunde später springt er auf -2.147.483.648, was als 13. Dezember 1901 gelesen wird. Jedes System, das die Zeit noch in einer vorzeichenbehafteten 32-Bit-Ganzzahl hält, springt in diesem Moment 137 Jahre in die Vergangenheit. Die Lösung ist ein einziges Wort: 64-Bit. Die Tabelle unten zeigt, welche Speichertypen betroffen und welche bereits sicher sind.
| Speichertyp | Überlauf bei / max. Datum | Sicher nach 2038? |
|---|---|---|
| Signed 32-Bit time_t / SQL INT | 2038-01-19 03:14:07 UTC | Nein |
| MySQL TIMESTAMP | 2038-01-19 03:14:07 UTC | Nein — DATETIME verwenden |
| Unsigned 32-Bit | 2106-02-07 06:28:15 UTC | Bringt 68 Jahre, keine Lösung |
| Signed 64-Bit time_t / SQL BIGINT | ~292 Milliarden Jahre | Ja |
| 64-Bit-Float (JavaScript, Python) | Jahr 275.760 | Ja |
| MySQL DATETIME (gepackte Felder) | Jahr 9999 | Ja |
Was ist das Jahr-2038-Problem?
Unix-Timestamps werden traditionell als vorzeichenbehaftete 32-Bit-Ganzzahl gespeichert, die Sekunden seit dem 1. Januar 1970 00:00:00 UTC zählt. Der Maximalwert einer vorzeichenbehafteten 32-Bit-Ganzzahl ist 2.147.483.647 — was dem 19. Januar 2038 um 03:14:07 UTC entspricht. Eine Sekunde nach diesem Moment läuft die Ganzzahl auf -2.147.483.648 über. Als Unix-Timestamp interpretiert entspricht dieser negative Wert dem 13. Dezember 1901 — und schickt betroffene Systeme fast 137 Jahre in die Vergangenheit.
- 2^31 − 1 = 2.147.483.647 (maximale vorzeichenbehaftete 32-Bit-Ganzzahl)
- 2.147.483.647 als Datum = 19. Januar 2038 03:14:07 UTC
- 2.147.483.647 + 1 läuft auf −2.147.483.648 über (der kleinste 32-Bit-Wert)
- −2.147.483.648 als Datum = 13. Dezember 1901 20:45:52 UTC
- Die lokale Zeit des Überlaufs variiert: 22:14:07 EST am 18. Januar, 14:14:07 JST am 19. Januar
Welche Systeme sind gefährdet?
Das Problem betrifft Systeme, die Timestamps als vorzeichenbehaftete 32-Bit-Ganzzahlen speichern:
- Eingebettete Systeme und Mikrocontroller mit 32-Bit-time_t
- Alter C- und C++-Code, für 32-Bit-Ziele kompiliert, der time_t oder int für Timestamps nutzt
- Alte Linux-Kernel (vor 5.6) auf 32-Bit-Hardware, noch im Produktiveinsatz
- MySQL-TIMESTAMP-Spalten — auf 2038-01-19 begrenzt; stattdessen DATETIME verwenden
- Manche Netzwerkprotokolle und Dateiformate, die Timestamps als 32-Bit-Werte kodieren
- Firmware in industriellen Steuerungssystemen und IoT-Geräten mit jahrzehntelanger Lebensdauer
Welche Systeme sind sicher?
Der größte Teil moderner Software und Infrastruktur ist bereits nicht betroffen:
- Jedes 64-Bit-Betriebssystem — Linux (glibc 2.34+ behebt es auch auf 32-Bit-Hardware), macOS, Windows
- Python — Timestamps nutzen 64-Bit-Floats, sicher weit über das Jahr 292 Millionen hinaus
- JavaScript — Date nutzt 64-Bit-IEEE-754-Floats, sicher bis zum Jahr 275.760
- Go und Rust — nutzen intern int64 für Zeit, sicher für Milliarden Jahre
- Java — java.time.Instant nutzt long (64-Bit), sicher bis zum Jahr ~292 Millionen
- PostgreSQL TIMESTAMP — speichert Daten nach 2038 korrekt
- MySQL DATETIME — Bereich 1000-01-01 bis 9999-12-31, nicht betroffen
MySQL TIMESTAMP und die 2038-Grenze
MySQL hat zwei Haupt-Datum-Zeit-Spaltentypen, die sich rund um 2038 sehr unterschiedlich verhalten:
- TIMESTAMP wird intern als vorzeichenbehaftete 32-Bit-Unix-Ganzzahl gespeichert — es läuft am 2038-01-19 03:14:07 UTC über
- DATETIME wird als gepackte Y/M/D h/m/s-Felder gespeichert und unterstützt bis zum Jahr 9999 — für jedes Datum nach 2038 verwenden
- TIMESTAMP konvertiert zudem implizit in/aus der Sitzungszeitzone des Servers; DATETIME speichert den Wert unverändert
- Für reine Epoch-Spalten BIGINT statt INT speichern, damit der Wert selbst nicht überlaufen kann
- Bestehende Schemas prüfen: SELECT TABLE_NAME, COLUMN_NAME FROM information_schema.COLUMNS WHERE DATA_TYPE = "timestamp"
Eingebettetes Linux und 32-Bit-time_t
Das größte verbleibende Y2038-Risiko liegt in langlebigen eingebetteten Systemen: Routern, Industriesteuerungen, Automotive-Steuergeräten, intelligenten Zählern und IoT-Geräten, die mit 32-Bit-Kernen ausgeliefert wurden und über 2038 hinaus im Einsatz bleiben können. Sowohl die C-Bibliothek als auch jegliche eigenen Binärprotokolle müssen 64-Bit-sauber sein.
- glibc erhielt 64-Bit-time_t für 32-Bit-ABIs über das Build-Makro -D_TIME_BITS=64 (glibc 2.34+)
- musl libc ist seit Version 1.2.0 (2020) standardmäßig 64-Bit-time_t
- Debian, Ubuntu und OpenWrt haben ihre 32-Bit-Ports alle auf 64-Bit-time_t migriert
- Dateisystem-Timestamps sind ein separates Thema: ext2/ext3 nutzen 32-Bit-Zeiten; ext4 unterstützt 64-Bit bei Inodes ≥ 256 Byte
- Bei Hardware, die 2026+ noch ausgeliefert wird, sowohl die C-Bibliothek als auch alle Wire-Formate auf 64-Bit prüfen
Wie man Y2038 behebt und testet
Die Lösung ist immer dieselbe — die Zeit auf 64 Bit verbreitern — muss aber auf jeder Schicht angewendet werden, die einen Timestamp speichert oder überträgt: die C-Bibliothek, die Datenbankspalten und jedes Binärprotokoll oder Dateiformat. Der schnellste Weg, ein Problem zu finden, ist, eine Uhr in einer Testumgebung über die Grenze zu stellen und auf Daten zu achten, die in 1901 landen.
- 32-Bit-Code mit -D_TIME_BITS=64 (und -D_FILE_OFFSET_BITS=64) unter glibc 2.34+ kompilieren
- BIGINT, nicht INT, für jede Spalte verwenden, die rohe Unix-Sekunden oder -Millisekunden speichert
- DATETIME oder TIMESTAMPTZ gegenüber MySQL TIMESTAMP für Daten bevorzugen, die 2038 überschreiten können
- In Tests die System- oder Container-Uhr auf 2038-01-19T03:14:08Z setzen und sicherstellen, dass Daten in 2038 bleiben
- Wire-Formate und Datei-Header prüfen — ein 64-Bit-Betriebssystem hilft nicht, wenn das Protokollfeld 32-Bit ist
Verwandte Rollover: Y2K, GPS, NTP und 2106
Das Jahr 2038 gehört zu einer Familie von Rollovern fester Breite. Jeder entsteht dadurch, dass eine Uhr in zu wenige Bits gepackt wird, und die Daten zu kennen hilft, den nächsten zu erkennen, bevor er ausgeliefert wird:
| Rollover | Datum | Ursache |
|---|---|---|
| Y2K | 2000-01-01 | Zweistellige Jahresspeicherung |
| GPS-Wochen-Rollover | 2019-04-06 | 10-Bit-GPS-Wochenzähler |
| NTP-Ära-Rollover | 2036-02-07 | Unsigned 32-Bit-Sekunden seit 1900 |
| Jahr 2038 (Y2K38) | 2038-01-19 | Signed 32-Bit-Sekunden seit 1970 |
| Jahr 2106 | 2106-02-07 | Unsigned 32-Bit-Sekunden seit 1970 |
Verwandte Referenzen
FAQ
- Was ist das Jahr-2038-Problem?
- Das Jahr-2038-Problem (Y2K38) ist ein Fehler, bei dem Systeme, die Unix-Timestamps in vorzeichenbehafteten 32-Bit-Ganzzahlen speichern, am 19. Januar 2038 um 03:14:07 UTC überlaufen. Der Maximalwert einer vorzeichenbehafteten 32-Bit-Ganzzahl ist 2.147.483.647. Eine Sekunde später springt die Ganzzahl auf -2.147.483.648, was dem 13. Dezember 1901 entspricht.
- Was ist der Unix-Timestamp für den 19. Januar 2038?
- Der Unix-Timestamp für den 19. Januar 2038 um 03:14:07 UTC ist 2.147.483.647 — der Maximalwert einer vorzeichenbehafteten 32-Bit-Ganzzahl (2^31 - 1). Das ist der exakte Moment, in dem der Jahr-2038-Überlauf auf 32-Bit-Systemen auftritt.
- Wie behebe ich das Jahr-2038-Problem?
- Speichere die Zeit in einer vorzeichenbehafteten 64-Bit-Ganzzahl statt in 32 Bit. Verwende 64-Bit-time_t (32-Bit-Code mit -D_TIME_BITS=64 unter glibc 2.34+ bauen), BIGINT statt INT für Epoch-Spalten und DATETIME statt MySQL TIMESTAMP. Ein vorzeichenbehafteter 64-Bit-Zeitwert läuft etwa 292 Milliarden Jahre lang nicht über.
- Ist Y2K38 dasselbe wie Y2K?
- Nein. Y2K (Jahr-2000-Problem) entstand dadurch, dass Programme Jahre als zweistellige Zahlen speicherten. Y2K38 entsteht dadurch, dass Unix-Timestamps als vorzeichenbehaftete 32-Bit-Ganzzahlen gespeichert werden, die 2038 überlaufen. Unterschiedliche Ursachen, unterschiedliche betroffene Systeme.
- Was ist das Jahr-2106-Problem?
- Jahr 2106 ist derselbe Überlauf für vorzeichenlose 32-Bit-Timestamps, die am 7. Februar 2106 um 06:28:15 UTC auslaufen. Der Wechsel von vorzeichenbehaftet zu vorzeichenlos 32-Bit bringt 68 weitere Jahre, ist aber keine echte Lösung; 64-Bit-Zeit ist es.
- Wird das Internet 2038 zusammenbrechen?
- Wahrscheinlich nicht in nennenswertem Umfang. Die meiste Internet-Infrastruktur ist bereits auf 64-Bit-Systeme migriert. Das Risiko konzentriert sich auf eingebettete Systeme, alte IoT-Geräte und seit Jahrzehnten nicht aktualisierte Software. Moderne Betriebssysteme, Programmiersprachen und Datenbanken sind bereits sicher.