For example the:
I created a function that calculates all the federal holidays (US), for any given year and returns them inside an array. I've tested it with several different years (from 2016 to 2024). Here is the code, please let me know if you find any miscalculations:
//function that checks if a holiday lands on saturday/sunday and so we can move them to a friday/monday respectively
private function getObservedDate($holidayDate){
$dayofweek = date("w", strtotime($holidayDate));
if ($dayofweek == 6) $holidayDate = date('m/d/Y', strtotime("$holidayDate - 1 days")); //saturday moves to friday
else if ($dayofweek == 0) $holidayDate = date('m/d/Y', strtotime("$holidayDate + 1 days")); //sunday moves monday
return $holidayDate;
}
//function that calculates the holidays for any given year
private function getFederalHolidaysForYear($year){
$NY = $this->getObservedDate( date('m/d/Y', strtotime("1/1/$year")) ); //new years day
$MLK = $this->getObservedDate( date('m/d/Y', strtotime("third monday of january $year")) ); //martin luther king day
$PD = $this->getObservedDate( date('m/d/Y', strtotime("third monday of february $year")) ); ; //presidents day
$MDay = $this->getObservedDate( date('m/d/Y', strtotime("last monday of May $year")) ); //memorial day
$IDay = $this->getObservedDate( date('m/d/Y', strtotime("7/4/$year")) ); // independence day
$LD = $this->getObservedDate( date('m/d/Y', strtotime("first monday of september $year")) ); //labor day
$VD = $this->getObservedDate( date('m/d/Y', strtotime("11/11/$year")) ); //veterans day
$ColD =$this->getObservedDate( date('m/d/Y', strtotime("second monday of october $year")) ); //columbus day
$TG = $this->getObservedDate( date('m/d/Y', strtotime("last thursday of november $year")) ); // thanksgiving
$CD = $this->getObservedDate( date('m/d/Y', strtotime("12/25/$year")) ); //christmas day
$nonWorkingDays = array();
array_push($nonWorkingDays, $NY, $MLK, $PD, $MDay, $IDay, $LD, $ColD, $VD, $TG, $CD);
return $nonWorkingDays;
}
You can leverage this function of php. strtotime
$currentYear = date("Y");
MLK Day -
echo date('Y-m-d', strtotime("third monday of january $currentYear"));
Presidents Day -
echo date('Y-m-d', strtotime("third monday/OD February $currentYear"));
Easter -
echo date('Y-m-d', strtotime("last sunday of march $currentYear"));
Memorial Day -
echo date('Y-m-d', strtotime("last monday of may $currentYear"));
Solution for moving holydays in Germany: returns an array of 'Y-m-d' formated strings including good friday, easter monday, ascencion, and pentecost monday. A new DateTime object for easter ist created for each day to enhance readability.
function beweglicheFeiertage( int $year ):array
{
//Karfreitag - good friday
$return = array();
$easterDate = DateTime::createFromFormat('U', easter_date($year) );
$easterDate->modify('- 1 days');
$return[] = $easterDate->format('Y-m-d');
//Ostermontag easter monday
$easterDate = DateTime::createFromFormat('U', easter_date($year) );
$easterDate->modify('+ 2 day');
$return[] = $easterDate->format('Y-m-d');
//Himmelfahrt ascencion
$easterDate = DateTime::createFromFormat('U', easter_date($year) );
$easterDate->modify('+ 40 days');//go to Ascencionday
$return[] = $easterDate->format('Y-m-d');
//Pfingstmontag - pentecost monday
$easterDate = DateTime::createFromFormat('U', easter_date($year) );
$easterDate->modify('+ 51 days');//go to Pentecost Monday
$return[] = $easterDate->format('Y-m-d');
return $return;
}
This way worked for me.
function observed_date($holiday){
$day = date("w", strtotime($holiday));
if($day == 6) {
$observed_date = $holiday -1;
} elseif ($day == 0) {
$observed_date = $holiday +1;
} else {
$observed_date = $holiday;
}
return $observed_date;
}
function get_holiday($holiday_name) {
$currentYear = date('Y');
switch ($holiday_name) {
// New Years Day
case "new_year":
$holiday = observed_date(date('Ymd', strtotime("first day of january $currentYear")));
break;
// Martin Luther King, Jr. Day
case "mlk_day":
$holiday = date('Ymd', strtotime("january $currentYear third monday"));
break;
// President's Day
case "presidents_day":
$holiday = date('Ymd', strtotime("february $currentYear third monday"));
break;
// Memorial Day
case "memorial_day":
$holiday = (new DateTime("Last monday of May"))->format("Ymd");
break;
// Independence Day
case "independence_day":
$holiday = observed_date(date('Ymd', strtotime("july 4 $currentYear")));
break;
// Labor Day
case "labor_day":
$holiday = date('Ymd', strtotime("september $currentYear first monday"));
break;
// Columbus Day
case "columbus_day":
$holiday = date('Ymd', strtotime("october $currentYear second monday"));
break;
// Veteran's Day
case "veterans_day":
$holiday = observed_date(date('Ymd', strtotime("november 11 $currentYear")));
break;
// Thanksgiving Day
case "thanksgiving_day":
$holiday = date('Ymd', strtotime("november $currentYear fourth thursday"));
break;
// Christmas Day
case "christmas_day":
$holiday = observed_date(date('Ymd', strtotime("december 25 $currentYear")));
break;
default:
$holiday = "";
break;
}
return $holiday;
}
Then you can print out the holiday by calling the function echo get_holiday('new_year');
And the result for 2015 should be 20150101
The strtotime function is useful here but it seems to have some peculiarities on how it interprets the English verbiage. Be sure to check your wording carefully and check your results.
For instance this seems like it should work, but it will return the last Monday in April ($currentYear = 2014)!
echo "Memorial Day " . date('F d, Y', strtotime("may $currentYear last monday")) . "<br />";
However, this phrasing will return the correct holiday for 2014.
echo "Memorial Day " . date('F d, Y', strtotime("last monday of May $currentYear")) . "<br />";
And this will give you the correct date for the holiday next year.
echo "Memorial Day " . date('F d, Y', strtotime("last monday of May $currentYear+1")) . "<br />";
The PHP doc page has additional comments on its use. Take care