Wochendenden und Feiertage mit PHP berechnen

veröffentlicht am 26. Oktober 2010

Gestern kam ich spontan auf die Idee, das folgende Problem zu lösen: anhand eines Datums soll PHP berechnen, ob es sich hierbei um einen freien Tag handelt. Zu den freien Tagen zähle ich in meinem Beispiel das Wochenende (Samstag und Sonntag) sowie die gesetzlichen Feiertage. Ich hatte eigentlich damit gerechnet, dass das ein schwieriges Unterfangen wird, aber eigentlich ist das alles ganz einfach.

Das folgende Beispiel ist für Schleswig-Holstein ausgelegt, das Script muss also für andere Bundesländer etwas angepasst werden. Dabei hilft diese Übersicht über alle Feiertage und deren Berechnung.

Feste Feiertage können einfach mit einem Datumscode eingetragen werden, bewegliche Feiertage werden (bis auf den Buß- und Bettag) in Deutschland in Relation zum Ostersonntag (Osterdatum) berechnet, für den es glücklicherweise direkt eine Funktion in PHP gibt. Alternativ kann man die Gaußsche Osterformel zur Berechnung des Ostersonntags benutzen.

Der folgende Codeschnipsel enthält keinerlei Überprüfungen der übergebenen Parameter, diese sollten für den produktiven Einsatz noch nachgepflegt werden.

function freierTag($tag, $monat, $jahr) {

   // Parameter in richtiges Format bringen
   if(strlen($tag) == 1) {
      $tag = "0$tag";
   }
   if(strlen($monat) == 1) {
      $monat = "0$monat";
   }

   // Wochentag berechnen
   $datum = getdate(mktime(0, 0, 0, $monat, $tag, $jahr));
   $wochentag = $datum['wday'];

   // Prüfen, ob Wochenende
   if($wochentag == 0 || $wochentag == 6) {
      return true;
   }

   // Feste Feiertage werden nach dem Schema ddmm eingetragen
   $feiertage[] = "0101"; // Neujahrstag
   $feiertage[] = "0105"; // Tag der Arbeit
   $feiertage[] = "0310"; // Tag der Deutschen Einheit
   $feiertage[] = "2512"; // Erster Weihnachtstag
   $feiertage[] = "2612"; // Zweiter Weihnachtstag

   // Bewegliche Feiertage berechnen
   $tage = 60 * 60 * 24;
   $ostersonntag = easter_date($jahr);
   $feiertage[] = date("dm", $ostersonntag - 2 * $tage);  // Karfreitag
   $feiertage[] = date("dm", $ostersonntag + 1 * $tage);  // Ostermontag
   $feiertage[] = date("dm", $ostersonntag + 39 * $tage); // Himmelfahrt
   $feiertage[] = date("dm", $ostersonntag + 50 * $tage); // Pfingstmontag

   // Prüfen, ob Feiertag
   $code = $tag.$monat;
   if(in_array($code, $feiertage)) {
      return true;
   } else {
      return false;
   }
}

Wie man sieht, ist die Berechnung von Wochendenden und Feiertagen recht einfach. Diese Berechnung kann man sicherlich auch schnell in anderen Programmiersprachen abbilden.

Kommentare

Ich hab’ Deine Funktion gekürzt – Ich brauche die Wochenenden nicht – und erweitert – Ich will anzeigen lassen, um welchen Feiertag es sich jeweils handelt. Funktioniert prima, in einem Kalender.
DANKE, daß ich Deine Arbeit benutzen durfte.
Peter

Kommentar #1 von Peter am 20. Februar 2012


Wow, das ist super! Vielen Dank für deine Mühe :)

Kommentar #2 von Phillip am 14. Mai 2012


Super Ding!
Genau so etwas habe ich gesucht.. vielen Dank.
Einfach und gut

Kommentar #3 von Mathias am 29. Juni 2012


Pingback #4 von Feiertage berechnen und ausgeben - php.de am 19. Juli 2012


Danke fuer die simple Umsetzung – effektiver code. Ich gehe mal davon aus das der code frei ist? Leider konnte ich keinen Hinweis auf copyrights oder Lizensierung finden.

Kommentar #5 von Olfried am 07. August 2012


@olfried: Kannst kopieren, ich bin ja nicht Oracle ;)

Kommentar #6 von Patrick am 07. August 2012


Hi danke für die function, hab noch eine ergänzung geschrieben um nächsten arbeitstag zu berechnen

function nextAtag($datum, $format="Y-m-d"){

	$startTime	= strtotime($datum);
	$d = 0;
	$sd ="";
	do {
		$jahr  = date('Y', strtotime('+'.$d.' day', $startTime));
		$monat = date('m', strtotime('+'.$d.' day', $startTime));
		$tag = date('d', strtotime('+'.$d.' day', $startTime));
	
		$b = freierTag($tag, $monat, $jahr);
		
		$sd = date($format, strtotime('+'.$d.' day', $startTime));
		
		++$d;
		
	} while ($b);
	
	return $sd;
}
Kommentar #7 von Andrey am 13. September 2012


Hallo, Patrick,
in Deinem Code ist alles in Ordnung.

Nur: easter_date() funktioniert manchmal nicht richtig.
Aber es gibt auch dafür eine Lösung
http://www.it-in-a-box.com/2012/12/ostern-tiefergelegt-mit-phps-easter_date-2/

Grüße

Norbert

Kommentar #8 von Norbert am 07. Dezember 2012


Super Code.
Wie kann ich es anstellen, dass ich einen Zeitraum markiere? Also z.B. eine Woche Urlaub.

Kommentar #9 von Reni am 04. Februar 2013


@Andrey: Man kann den nächsten Werktag (Wochentag) auch per strtotime berechnen (http://stackoverflow.com/questions/4261179/working-days-mon-fri-in-php).

Gruß,
Daniel

Kommentar #10 von Daniel am 19. Februar 2013


Echt klasse der Code, danke! :)

Kommentar #11 von Benny am 30. Oktober 2013


Pingback #12 von Anonymous am 10. Dezember 2013



Erstmal danke für den Post. Ich hätte nicht gedacht, dass die Berechnung der Feiertage so simpel ist. Coole Sache! Nur mal so zur Info: du kannst am Ende deiner Funktion direkt return in_array($tag.$monat, $feiertage); machen. So sparst du dir dieses behinderte if Konstrukt. Sieht auch gleich viel besser aus ;-)

Kommentar #14 von Alexxus am 16. April 2014


Hinterlasse einen Kommentar