Wie berechnet man zu einer gegebenen Kalenderwoche das entsprechende Montagsdatum? Selbst eine Suche per IRC, Google, Usenet und Mailingliste brachte keine befriedigenden Ergebnisse. Hinweise, dass es in einer der PEAR Pakete etwas zum Thema Berechnung gäbe, konnten aber nicht abschließend verifiziert werden, da man für die Lösung der Problemstellung kein weiteres bloated OO Paket installieren wollte.
Doch nun kurz zur Theorie: die 1. Kalenderwoche eines Jahres ist in ISO8601 als die Kalenderwoche definiert, die den ersten Donnerstag des Jahres enthält.
Von einem gegebenen Timestamp die Kalenderwoche zu errechnen ist nicht schwer:
date(‚W‘,$timestamp);
Aus der Theorie folgt der Schluss: um von einer gegebenen Kalenderwoche auf das entsprechende Datum des Montags in dieser KW zu kommen, muss man zunächst das Datum des Montags in der 1. Kalenderwoche bestimmen und dann einfach nach vorne rechnen. Warum? Weil die 1. Kalenderwoche eines Jahres bereits im Jahr davor beginnen kann. Beispiel: der 29. Dezember 2003 war der Montag der 1. KW des Jahres 2004.
Wie rechnet man nun auf den Montag der 1. KW eines Jahres? Dazu benötigt man die Werkzeuge mktime, date und ein paar Additionen, Subtraktionen und Multiplikationen. Doch zunächst der Reihe nach:
Berechnung des Wochentags des 1.1. des gewünschten Jahres. Sei $tag=1 und $monat=1 und $jahr=2004, so schriebe man $wtag = date(‚w‘,mktime (0,0,0,$monat,$tag,$jahr)); , um an die numerische Repräsentation des Wochentags des 1.1.2004 zu kommen. Heraus kommt, dass $wtag in diesem Fall eine 4 darstellt, also einen Donnerstag.
Laut Regel: die 1. Kalenderwoche eines Jahres ist die Woche, die den ersten Donnerstag des Jahres enthält, ist also $wtag <= 4. So muss man auf den Montag davor rechnen, um den Montag der 1. Kalenderwoche eines Jahres zu erhalten. Andernfalls muss man auf den darauf folgenden Montag rechnen. In eine Funktion eingetütet würde man also folgender maßen schreiben:
Die Funktion liefert, zur einfacheren Verwertung, einen Unix Timestamp zurück. Nun ist das 1. Etappenziel erreicht: zu einem gegebenen Jahr kann der Timestamp des Montags der 1. KW in diesem Jahr bekommen werden. Zeit für Hilfsfunktion 2: diese soll zu einer bestimmten KW eines Jahres den Timestamp des Montags in dieser KW zurückliefern. Die Idee ist einfach:
gib mir den Montag der 1. KW des gegebenen Jahres und addiere ($kw-1)*7 Tage darauf ($kw ist die gegebene Kalenderwoche des Jahres).
Einen großen Nutzen bei Datumsberechnungen aller Art liefert Ihnen mktime (). Sie können zum 1.1.2004 einfach 178 Tage drauf rechnen, und sie landen im richtigen Monat im richtigen Jahr. Auf Basis des Timestamps, den Ihnen mondaykw() zurückliefert, können Sie nun Ihren Kalender für die aktuell (z.B. per $_GET übergebene) ausgewählte Kalenderwoche aufbauen.
Björn Schotte ist Web Application Developer und Consultant. Neben seiner Erfahrung in vielen Webprojekten/Schulungen, u.a. für Lycos Europe, Cap Gemini Ernst & Young, Karlsruher Versicherungen, 100world.com AG, 21st Media, betreibt er auch noch einige nicht-kommerzielle Projekte wie zum Beispiel das PHP-Center www.php-center.de/.
Copyright
Alle Rechte an diesem Artikel sind Björn Schotte vorbehalten. Nachdruck und Vervielfältigung der redaktionellen Texte einschließlich Speicherung und Nutzung auf optischen und elektronischen Datenträgern nur mit Zustimmung von Björn Schotte und ZDNet.
Neueste Kommentare
2 Kommentare zu Tage einer Kalenderwoche für einen Web-basierten Kalender berechnen
Kommentar hinzufügenVielen Dank für Ihren Kommentar.
Ihr Kommentar wurde gespeichert und wartet auf Moderation.
Datumsscript
ich möchte mir gerne den ersten und letzten Tag einer Kalenderwoche anzeigen lassen. Das funktioniert soweit auch mit:
$ersterWT=date(‚d.m‘, mondaykw($kw,$jahr));
$letzterWT=date(‚d.m‘, mondaykw($kw,$jahr))+4;
Leider habe ich Probleme wenn die Woche einen Monatswechsel enthält.
Aktuell Zeigt er mir "28.05 bis 32.05.2012" anstatt "bis 01.06.2012" an.
Wie kann ich dies realisieren?
Fehler wenn Vorjahr 53 Kalenderwochen hat
In mondaykw() funktioniert "$tage = ($kw-1)*7;" allerdings nur wenn das Jahr davor nicht 53 Kalenderwochen hat. Folgendes funktioniert dagegen.
$x = (date("W", mktime (0, 0, 0, 12, 28, $jahr-1)) == 53) ? 0 : 1;
$tage = ($kw-x)*7;