PHP-Skript: Datumsdifferenz in Jahren, Monaten und Tagen

Dieses Tutorial zeigt, wie man mit PHP den Abstand zweier Datumsangaben berechnet, die als UNIX-Zeitstempel vorliegen. Während die Berechnung auf Basis einer einzigen Einheit (z.B. die Anzahl der Tage) sehr einfach, aber für uns als Menschen häufig sehr wenig anschaulich ist, gestaltet sich die gemischte Angabe in Jahren, Monaten und Tagen etwas schwieriger.

Anwendungsbeispiel

Es sind mittlerweile 22 Jahre, 6 Monate und 13 Tage seit dem Fall der Berliner Mauer vergangen.

Wir müssen uns noch 3 Jahre, 1 Monate und 23 Tage gedulden, bis die Raumsonde New Horizons den Pluto erreicht.

Voraussetzungen

Die beiden Datumsangaben liegen in den Variablen $date1 und $date2 als Ganzzahl in Form eines UNIX-Zeitstempels vor. Solch einen UNIX-Zeitstempel liefert zum Beispiel die time()-Funktion für das aktuelle Datum zurück, kann aber ebenso mit der mktime()-Funktion von einem beliebigen Datum erstellt werden. Beispiel:

$date1 = time(); $date2 = mktime(12, 0, 0, 7, 14, 2015);

Kommentiertes Skript

Zu allererst stellen wir sicher, dass das zweite übergebene Datum auch das größere der beiden ist; das erspart uns später einigen Ärger. Für den Fall, dass doch das erste Datum das größere ist, tauschen wir den Inhalt der Variablen $date1 und $date2 miteinander. Dafür verwendet man üblicherweise den Dreieckstausch. Da die beiden Daten jedoch als Ganzzahlen vorliegen, können wir hier einen optimierten Tausch auf Basis einiger binärer XOR-Operationen durchführen (zur Erklärung siehe weiterführende Links).

if ($date1 > $date2) $date1 ^= $date2 ^= $date1 ^= $date2;

Nun bestimmen wir mit Hilfe der date()-Funktion die einzelnen Partikel der beiden Datumsangaben.

$day1 = date('d', $date1); $month1 = date('m', $date1); $year1 = date('Y', $date1); $day2 = date('d', $date2); $month2 = date('m', $date2); $year2 = date('Y', $date2);

Nachdem wir diese Vorarbeit geleistet haben, machen wir uns daran die Differenz der Datumsangaben zu berechnen. Das ganze funktioniert im Prinzip wie eine schriftliche Subtraktion, bei der die Tage die kleinste Stelle, die Jahre die größte Stelle bilden:

Ist die obere Zahl größer als die untere, können wir problemlos subtrahieren. Ist es andersherum, würden wir dagegen einen negativen Wert erhalten. Wir leihen uns daher schon etwas von der nächsten Stelle, indem wir einen Übertrag machen. Da in unserem Dezimalsystem jede Stelle den zehnfachen Wert der vorherigen hat, erhalten wir so generell 10 dazu. Bei Datumsangaben gestaltet sich das ungleich schwerer, wie wir gleich sehen werden.

Beginnen wir also mit der Differenz der Tage. Erhalten wir dabei einen negativen Wert, so setzen wir einen Übertrag in der Variable $carry und leihen uns damit den Wert eines Monats. Das Problem: ein Monat kann 31 oder 30 Tage umfassen, der Februar zudem 28, in Schaltjahren 29. Wir müssen daher herausbekommen, wie viel Tage der Monat hat, in dem das kleinere Datum liegt, damit wir überhaupt wissen, welchen Zugewinn wir durch das Leihen eines Monats erhalten. Glücklicherweise bietet uns die date()-Funktion mit dem Parameter t eine einfache Möglichkeit die Anzahl der Tage eines Monats zu bestimmen, die sogar Schaltjahre korrekt berücksichtigt.

$days = $day2 - $day1; if ($days < 0) { $days += date('t', $date1); $carry = 1; } else $carry = 0;

Weiter geht es mit den Monaten. Hier müssen wir zunächst den Übertrag der vorherigen Rechnung berücksichtigen. Gegebenenfalls müssen wir uns auch bei den Monaten ein Jahr leihen. Glücklicherweise hat jedes Jahr 12 Monate, sodass sich der Übertrag hier einfach gestaltet.

$months = $month2 - $month1 - $carry; if ($months < 0) { $months += 12; $carry = 1; } else $carry = 0;

Und zum Abschluss noch die Jahre. Hier können sich keine negativen Werte mehr ergeben, da wir oben ja bereits sichergestellt hatten, dass das zweite Datum stets größer als das erste Datum ist.

$years = $year2 - $year1 - $carry;

Das Ergebnis der ganzen Rechnerei können wir nun beliebig ausgeben, beispielsweise:

echo $years . ' Jahre, ' . $months . ' Monate und ' . $days . ' Tage'

Skript zum Herunterladen

Das Skript ist in einer Textdatei mit der Kodierung ISO-8859-1 hinterlegt, damit es nicht vom PHP-Interpreter auf meinem Webspace ausgeführt wird und Sie es herunterladen können. Sie können den benötigten Programmcode entweder in Ihr Skript hinüberkopieren oder aber das Skript speichern und die Endung auf .php ändern.

datumsdifferenz-in-jahren-monaten-und-tagen.txt