Wer einen Wochenkalender, Schichtplan oder Projektplan in PHP programmiert, kommt um Kalenderwochen nicht herum. Dieses Tutorial zeigt Schritt für Schritt, wie du die aktuelle Kalenderwoche ermittelst, das Start- und Enddatum einer beliebigen KW berechnest und typische Fehler am Jahreswechsel vermeidest.
Was sind Kalenderwochen nach ISO 8601?
Die Kalenderwoche (KW) nach ISO 8601 ist ein internationaler Standard zur Nummerierung von Wochen. Die wichtigsten Regeln:
- Jede Woche beginnt am Montag und endet am Sonntag.
- KW 1 ist die Woche, die den ersten Donnerstag des Jahres enthält.
- Ein ISO-Jahr hat 52 oder 53 Kalenderwochen.
Kalenderwochen werden häufig in Anwendungen wie Wochenberichten, Schichtplänen, Projektplanungen und Kalenderansichten benötigt. PHP bietet dafür leistungsfähige Funktionen, die in diesem Tutorial vorgestellt werden.
Hinweis: Für die Grundlagen von date(), DateTimeImmutable und weiteren Datumsfunktionen in PHP siehe das Tutorial Datum und Zeit ausgeben mit PHP.
Aktuelle Kalenderwoche ermitteln
Die aktuelle Kalenderwoche lässt sich in PHP auf zwei Wegen ermitteln, prozedural mit date() oder objektorientiert mit DateTimeImmutable:
<?php
// Prozedural
echo date('W'); // z.B. "08"
// Objektorientiert
$heute = new DateTimeImmutable();
echo $heute->format('W'); // z.B. "08"
?>
Der Formatparameter W liefert die Kalenderwoche mit führender Null (01 bis 53).
ISO-Jahr vs. Kalenderjahr
Ein häufiger Fehler ist die Verwechslung von date('Y') (Kalenderjahr) und date('o') (ISO-Jahr). Am Jahreswechsel können sich diese unterscheiden:
<?php
/* Beispiel: 1. Januar 2026 (Donnerstag)
= KW 1 von 2026 */
$datum = new DateTimeImmutable('2026-01-01');
echo $datum->format('Y') . ' / KW ' . $datum->format('W'); // 2026 / KW 01
echo $datum->format('o') . ' / KW ' . $datum->format('W'); // 2026 / KW 01
/* Beispiel: 29. Dezember 2025 (Montag)
= KW 1 von 2026! */
$datum2 = new DateTimeImmutable('2025-12-29');
echo $datum2->format('Y') . ' / KW ' . $datum2->format('W'); // 2025 / KW 01
echo $datum2->format('o') . ' / KW ' . $datum2->format('W'); // 2026 / KW 01
?>
Wichtig: Verwende immer date('o') in Kombination mit date('W'), um das korrekte ISO-Jahr zur Kalenderwoche zu erhalten.
Start- und Enddatum einer Kalenderwoche berechnen
Das ist das Kernthema dieses Tutorials: Wie berechnet man den Montag (Start) und Sonntag (Ende) einer bestimmten Kalenderwoche?
Mit DateTimeImmutable (empfohlen)
PHP kann das ISO-8601-Wochenformat direkt parsen. Das Format lautet AAAAWkk, wobei AAAA das ISO-Jahr und kk die zweistellige Kalenderwoche ist:
<?php
$kw = 8;
$jahr = 2026;
// Montag der KW berechnen
$montag = new DateTimeImmutable(sprintf('%04dW%02d', $jahr, $kw));
// Sonntag der KW berechnen
$sonntag = $montag->modify('+6 days');
echo 'KW ' . $kw . '/' . $jahr . ': ';
echo $montag->format('d.m.Y') . ' – ' . $sonntag->format('d.m.Y');
// KW 8/2026: 16.02.2026 – 22.02.2026
?>
Alle Tage einer Kalenderwoche auflisten
Um alle sieben Tage einer Kalenderwoche auszugeben, wird der Montag als Startpunkt verwendet und jeweils ein Tag addiert:
<?php
$kw = 8;
$jahr = 2026;
$montag = new DateTimeImmutable(sprintf('%04dW%02d', $jahr, $kw));
for ($i = 0; $i < 7; $i++) {
$tag = $montag->modify("+{$i} days");
echo $tag->format('l, d.m.Y') . "n";
}
// Monday, 16.02.2026
// Tuesday, 17.02.2026
// ...
// Sunday, 22.02.2026
?>
Für deutsche Wochentage kann IntlDateFormatter oder ein eigenes Mapping verwendet werden. Mehr dazu im Tutorial Datum und Zeit ausgeben mit PHP.
Praxisbeispiel: Wochen-Navigation
Ein typischer Anwendungsfall ist die Navigation zwischen Kalenderwochen, z.B. in einem Wochenkalender oder Schichtplan. Dabei muss der Jahreswechsel korrekt berücksichtigt werden:
<?php
// Aktuelle KW und ISO-Jahr als Standard
$kw = (int) ($_GET['kw'] ?? date('W'));
$jahr = (int) ($_GET['jahr'] ?? date('o'));
// Start- und Enddatum
$montag = new DateTimeImmutable(sprintf('%04dW%02d', $jahr, $kw));
$sonntag = $montag->modify('+6 days');
// Vorherige Woche
$vorher = $montag->modify('-7 days');
$kwVorher = (int) $vorher->format('W');
$jahrVorher = (int) $vorher->format('o');
// Nächste Woche
$nachher = $montag->modify('+7 days');
$kwNachher = (int) $nachher->format('W');
$jahrNachher = (int) $nachher->format('o');
?>
<a href="?kw=<?= $kwVorher ?>&jahr=<?= $jahrVorher ?>">
← KW <?= $kwVorher ?>
</a>
<strong>KW <?= $kw ?> / <?= $jahr ?></strong>
<a href="?kw=<?= $kwNachher ?>&jahr=<?= $jahrNachher ?>">
KW <?= $kwNachher ?> →
</a>
Durch die Verwendung von modify('-7 days') und format('o')/format('W') wird der Jahreswechsel automatisch korrekt behandelt. So funktioniert zum Beispiel auch der Sprung von KW 1/2026 zurück auf KW 53/2025 ohne Probleme.
Praxisbeispiel: Alle Kalenderwochen eines Jahres
Dieses Beispiel zeigt, wie alle Kalenderwochen eines Jahres mit Start- und Enddatum aufgelistet werden. Zuerst muss ermittelt werden, ob das Jahr 52 oder 53 Wochen hat:
<?php
$jahr = 2026;
// Anzahl der Kalenderwochen ermitteln
$letzterTag = new DateTimeImmutable($jahr . '-12-28');
$anzahlKW = (int) $letzterTag->format('W');
echo "Jahr $jahr hat $anzahlKW Kalenderwochennn";
echo "KW | Montag | Sonntagn";
echo "----|------------|----------n";
for ($kw = 1; $kw <= $anzahlKW; $kw++) {
$montag = new DateTimeImmutable(sprintf('%04dW%02d', $jahr, $kw));
$sonntag = $montag->modify('+6 days');
echo sprintf(
"%2d | %s | %sn",
$kw,
$montag->format('d.m.Y'),
$sonntag->format('d.m.Y')
);
}
?>
Warum der 28. Dezember? Der 28. Dezember liegt immer in der letzten Kalenderwoche des Jahres. Damit lässt sich zuverlässig ermitteln, ob ein Jahr 52 oder 53 Kalenderwochen hat.
Sonderfälle und Fallstricke
Bei der Arbeit mit Kalenderwochen gibt es einige Besonderheiten, die immer wieder zu Fehlern führen. Gerade am Jahreswechsel lauern Überraschungen.
KW 1 kann im Vorjahr beginnen
Da KW 1 die Woche mit dem ersten Donnerstag des Jahres ist, kann sie bereits am 29., 30. oder 31. Dezember des Vorjahres beginnen:
<?php
// KW 1 von 2026 beginnt am 29.12.2025
$kw1 = new DateTimeImmutable('2026W01');
echo $kw1->format('d.m.Y'); // 29.12.2025
?>
KW 53 existiert nicht in jedem Jahr
Die meisten Jahre haben 52 Kalenderwochen. KW 53 gibt es nur, wenn der 1. Januar auf einen Donnerstag fällt (oder bei Schaltjahren auf Mittwoch oder Donnerstag). Einige Jahre mit KW 53: 2004, 2009, 2015, 2020, 2026, 2032.
<?php
// Prüfen, ob ein Jahr KW 53 hat
function hatKW53(int $jahr): bool
{
$letzterTag = new DateTimeImmutable($jahr . '-12-28');
return (int) $letzterTag->format('W') === 53;
}
echo hatKW53(2025) ? 'Ja' : 'Nein'; // Nein
echo hatKW53(2026) ? 'Ja' : 'Nein'; // Ja
?>
Führende Null im ISO-Wochenformat
Der String für den DateTimeImmutable-Konstruktor muss die Kalenderwoche zweistellig angeben: 2026W08 ist korrekt, 2026W8 führt zu einem Fehler. Die Funktion sprintf('%04dW%02d', $jahr, $kw) stellt das sicher.
FAQ
Die folgenden Fragen tauchen bei der Arbeit mit Kalenderwochen in PHP besonders häufig auf.
Wie bekomme ich die Kalenderwoche eines bestimmten Datums?
<?php
$datum = new DateTimeImmutable('2026-03-15');
echo 'KW ' . $datum->format('W'); // KW 11
echo 'ISO-Jahr: ' . $datum->format('o'); // ISO-Jahr: 2026
?>
Hat jedes Jahr 52 Kalenderwochen?
Nein. Die meisten Jahre haben 52, aber manche haben 53 Kalenderwochen. Dies hängt davon ab, auf welchen Wochentag der 1. Januar fällt. Die Funktion hatKW53() aus dem Abschnitt „Sonderfälle“ zeigt, wie man das prüft.
Warum zeigt mein Code für den 1. Januar die falsche KW?
Weil date('Y') das Kalenderjahr liefert, nicht das ISO-Jahr. Am 1. Januar 2027 ist z.B. noch KW 53 von 2026. Lösung: date('o') statt date('Y') verwenden.
<?php
$neujahr = new DateTimeImmutable('2027-01-01');
echo $neujahr->format('Y') . ' / KW ' . $neujahr->format('W'); // 2027 / KW 53
echo $neujahr->format('o') . ' / KW ' . $neujahr->format('W'); // 2026 / KW 53
?>
Kann ich auch Sonntag als Wochenstart verwenden?
Der ISO-8601-Standard definiert Montag als Wochenstart. PHP hält sich an diesen Standard. Wenn trotzdem Sonntag als Start benötigt wird, kann der berechnete Montag um einen Tag zurückgesetzt werden:
<?php
$kw = 8;
$jahr = 2026;
// ISO-Montag berechnen
$montag = new DateTimeImmutable(sprintf('%04dW%02d', $jahr, $kw));
/* Sonntag als Wochenstart
(ein Tag vor dem ISO-Montag) */
$sonntagStart = $montag->modify('-1 day');
$samstagEnde = $montag->modify('+5 days');
echo $sonntagStart->format('d.m.Y') . ' – ' . $samstagEnde->format('d.m.Y');
// 15.02.2026 – 21.02.2026
?>
Hinweis: Diese Woche entspricht dann nicht mehr der ISO-Definition und die KW-Nummerierung weicht ab.
Zusammenfassung
PHP bietet mit DateTimeImmutable und dem ISO-Wochenformat (AAAAWkk) eine elegante Möglichkeit, Kalenderwochen zu berechnen. Die wichtigsten Punkte:
format('W') liefert die Kalenderwoche, format('o') das zugehörige ISO-Jahr. new DateTimeImmutable('2026W08') erzeugt direkt den Montag der KW 8. - Der 28. Dezember liegt immer in der letzten KW des Jahres.
- Am Jahreswechsel immer
format('o') statt format('Y') verwenden.
Für weiterführende Informationen zu Datums- und Zeitfunktionen in PHP siehe das umfassende Tutorial Datum und Zeit ausgeben mit PHP.