Derzeit online: ca. 80 User  
Spenden via PayPal PHP für dich ist auch als Buch erhältlich - im handlichen Format, zum Nachschlagen, Mitnehmen oder gemütlichen nebenbei Lesen. Mit noch mehr Informationen, zusätzlichen Beispielen und Übungsaufgaben.
Jetzt in der aktualisierten Version bei Amazon oder BoD bestellen!


Schnipsel

PHP - Adventssonntage und andere Feiertage berechnen

Ich wollte herausfinden, wie man das korrekte Datum für den 1. Advent eines beliebigen Jahres berechnen kann und machte mich einfach mal aus Spaß an die Programmierung. Rechnereien mit Datumsangaben finde ich immer schwierig, weil Computer dabei ganz anders denken, als wir Menschen und ich es oft umständlich finde umzudenken und Dinge so ganz anders auszudrücken. Manchmal sind wir Menschen auch nicht ordentlich oder genau genug, da ist uns der Computer einfach einen Schritt voraus. Vor allem dann, wenn es um komplexe Daten geht. Das ist auch der Grund dafür, dass Unternehmen ihre Betriebsdatenerfassung und alles rund um die Zeitwirtschaft an Fachleute wie die hier verlinkten auslagern. Dort passieren dann Rechnereien, mit denen aussagekräftige Daten generiert werden. Bei meinem Problem mit dem 1. Advent hatte ich aber nach einer Weile eine funktionierende Lösung, die auch gar nicht so furchtbar umständlich war, wie ich befürchtet hatte. Danach machte ich mich im Internet auf die Suche nach fertigen Lösungen, weil ich sie miteinander vergleichen wollte. Relativ schnell stieß ich dabei auf die Funktion strtotime, die tatsächlich wesentlich besser und einfacher ist. Wenn man sie erstmal verstanden hat.

Die Erklärung bei php.net brachte mich nämlich zunächst nicht wirklich weiter. Dort steht: Wandelt ein beliebiges in englischer Textform angegebenes Datum in einen UNIX-Zeitstempel (Timestamp) um.

Okay, Timestamp war mir klar, ich würde also das Ergebnis noch formatieren müssen, aber was versteht man denn bitte unter "ein beliebiges in englischer Textform angegebenes Datum"? Ein sehr schwammiger Begriff.

Die Beispiele zeigten aber sehr schnell, dass strtotime in der Lage ist, unheimlich viele Begriffe zu interpretieren. Man kann z. B. ganz einfach den heutigen Tag in einer Woche angeben lassen, indem man strtotime("+1 week") verwendet. Das gleiche funktioniert natürlich auch mit +1 day oder anderen Angaben. Das ist aber noch nicht alles, man kann sogar sagen, dass man Donnerstag in drei Wochen haben mag, indem man +3 thursday verwendet, oder ähnliche Konstrukte bildet. Zusätzlich kann man auch noch ein beliebiges Datum angeben, von dem aus die Berechnungen stattfinden soll. Man muss es zwar in einen Timestamp umwandeln, aber das ist dank mktime überhaupt kein Problem.

Was das jetzt alles mit dem 1. Advent zu tun hat?

Google hat mir verraten, dass der 1. Advent immer der 1. Sonntag nach dem 26. November ist (das kann man sich natürlich auch selber überlegen ;-)). Ich füttere strtotime also mit diesen Angaben:
<?php
$erster_advent = strtotime("+1 sunday",mktime(0,0,0,11,27,2010));
?>
+1 sunday sorgt dafür, dass der folgende Sonntag berechnet wird. Wenn man nach dem Komma noch einen gültigen Timestamp angibt (oder direkt über mktime berechnen lässt), kann man auch exakt angeben, auf welchen Tag denn der Sonntag folgen soll. In diesem Fall mache ich also mktime-Angaben, die den 27.11.2010 ergeben.

Um das Ergebnis für uns lesbar auszugeben, sollten wir es noch über date formatieren. Das sieht dann so aus:
<?php
echo date("d.m.Y", $erster_advent);
?>
Man kann die beiden Angaben natürlich auch zusammenfassen und das Datum direkt ausgeben und auf die Speicherung in einer Variable verzichten.
<?php
echo date(strtotime("+1 sunday",mktime(0,0,0,11,27,2010)));
?>
In meinem Fall habe ich das Script noch dahingehend erweitert, dass man beim Seitenaufruf festlegen kann, für welches Jahr die Ausgabe erfolgen soll. Die per get übergebene Variable wird aus Sicherheitsgründen noch überpüft. Alles zusammen sieht es dann wie folgt aus:
<?php
if(is_int(intval($_GET["jahr"])))
{
  $jahr = intval($_GET["jahr"]);
}
else
{
  $jahr = date("Y");
}
echo "Adventssonntage im Jahr ",$jahr,": <br />";
echo "1. Advent: ",date("d.m.Y",strtotime("+1 sunday",mktime(0,0,0,11,27,$jahr))),"<br />";
echo "2. Advent: ",date("d.m.Y",strtotime("+2 sunday",mktime(0,0,0,11,27,$jahr))),"<br />";
echo "3. Advent: ",date("d.m.Y",strtotime("+3 sunday",mktime(0,0,0,11,27,$jahr))),"<br />";
echo "4. Advent: ",date("d.m.Y",strtotime("+4 sunday",mktime(0,0,0,11,27,$jahr))),"<br />";
?>
Wenn man immer nur das aktuelle Jahr verwenden möchte, kann man natürlich die Abfrage der get-Variable weglassen und entweder nur $jahr = date("Y"); nehmen, oder direkt in der mktime-Anweisung date("Y") angeben, das würde dann so aussehen:
<?php
echo "1. Advent: ",date("d.m.Y",strtotime("+1 sunday",mktime(0,0,0,11,27,date("Y"))),"<br />";
?>
Ausgegeben bekommen wir dann:

Adventssonntage im Jahr 2017:
1. Advent: 03.12.2017
2. Advent: 10.12.2017
3. Advent: 17.12.2017
4. Advent: 24.12.2017

Auf die gleiche Weise ist es natürlich auch möglich all die (Feier)tage zu berechnen, die sich auf Ostern beziehen (also Rosenmontag, Aschermittwoch, Himmelfahrt, Pfingsten, etc.). In dem Fall muss man dann als zweite Angabe für strtotime das Osterdatum verwenden. Und so kann ich euch jetzt z. B. verraten, dass der nächste Rosenmontag am 12.02.2018 ist (jeweils 48 Tage vor dem Ostersonntag).

Autor: Claudia Unkelbach
© 2001 - 2017 Claudia Unkelbach
Gießener Straße 75, 35396 Gießen