PHPGangsta - Der praktische PHP Blog

PHP Blog von PHPGangsta


Archive for the ‘2038 bug’ tag

Das Y2K38 Problem

with 18 comments

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.

Written by Michael Kliewe

Juni 7th, 2011 at 9:09 am

Posted in PHP

Tagged with , , ,