Archive for the ‘Timestamp’ tag
Die lieben Zeitzonen
Gastartikel von Arno Hollosi.
Kurz zu meiner Person: Ich arbeite seit über 13 Jahren mit PHP, betreibe ein recht erfolgreiches Wiki (Sensei’s Library) und habe in den letzten Jahren zwei Bücher veröffentlicht: PHP programmieren unter Windows (auch ins Englische übersetzt) und das vor kurzem hier verloste Buch Leistungsstarke PHP-Anwendungen.
Wenn Ihr genaue Uhrzeiten in eurer Applikation verwalten müsst, merkt ihr bald, dass das Thema komplexer als angenommen ist: Nicht nur, dass die Erde eine Kugel ist, nein, zudem hat sich Anfang des vergangenen Jahrhunderts die Idee der Sommerzeit durchgesetzt und auch Regierungen ändern gelegentlich die Zeit ihres Landes.
Das Y2K38 Problem
Wer viel mit Terminen und Datumsangaben arbeitet kennt das Problem vielleicht, aber häufig fällt uns das Problem jetzt noch nicht auf, und in einigen Jahren werden wir dann Probleme bekommen.
Es geht um den Unix Timestamp, also die Anzahl der Sekunden seit 1970. In PHP arbeiten Funktionen wie time() und strtotime() mit diesem Timestamp, aktuell heute liegt diese Zahl bei ca. 1,3 Milliarden (1307428397). Wenn wir nun mit Geburtsdaten arbeiten und jemand hat vor 1970 Geburtstag, dann können wir bekannterweise nicht den Timestamp nutzen. Aber es gibt auch eine obere Grenze, und kaum jemand weiß wo diese liegt. PHP arbeitet im 32-bit-Modus mit 4-Byte signed Integers, also vorzeichenbehaftete Zahlen zwischen -2.147.483.647 und 2.147.483.647, aktuell sind wir mit 1,3 Milliarden bereits über die Hälfte vorangeschritten. Exakt am 19.01.2038 um 03:14:07 werden wir einen Überlauf haben, der Timestamp wird also von 2.147.483.647 auf -2.147.483.647 umspringen, und negative Timestamps bedeuten immer 01.01.1970.
Mit einem Zweizeiler können wir zeigen dass wir bei Timestamps größer 2038 ein Problem bekommen:
<? $date = strtotime('2037-02-01'); echo date('d.m.Y H:i', $date);
Die Ausgabe in diesem Fall lautet 01.02.2037 00:00.
<? $date = strtotime('2039-02-01'); echo date('d.m.Y H:i', $date);
Hier haben wir das Maximum überschritten, es wird ausgegeben: 01.01.1970 01:00.
Aber nicht nur PHP hat Probleme damit, sehr viele Programmiersprachen, Programme und Betriebssysteme sind betroffen. Und da wir alle wissen wie lang einige Programme laufen werden (na, wer muss noch mit alten Cobol-Programmen arbeiten, oder Intranetseiten von 1995 nutzen?), oder man Termine für die Zukunft plant, sollte man schon jetzt mit dem Problem vertraut sein, um nicht schwer zu findende Bugs zu produzieren.
Es gibt mehrere Lösungen um das Problem zu umgehen. Entweder man arbeitet mit 64-bit Systemen und Software, die 8-Byte signed Integers nutzen, um damit das Problem effektiv zu beseitigen. Eine zweite Möglichkeit ist die Zeit in einem String zu speichern, also einfach „2045-05-27“ speichern und dann mit Hilfe der DateTime Klassen diesen String umwandeln und mit ihm rechnen:
$date = new DateTime('2045-05-27'); echo $date->format('d.m.Y H:i');
Gibt aus: 27.05.2045 00:00.
Also kurz drüber nachdenken wenn ihr das nächste Mal Unix Timestamps nutzt die in der Vergangenheit oder der Zukunft liegen, oder falls euer Programm evtl. auch noch in 27 Jahren laufen wird.