Working on a snippet that will generate a list of weekdays over the next couple of months. Within this list I wish to exclude a number of specific dates such as Public Holidays. These excluded dates will eventually be provided through a MIGX output (not sure how to do this bit yet).
So far I have been working on getting list of days and am stuck on excluding certain dates. I found a discussion on [https://stackoverflow.com/questions/16132356/php-exclude-dates-from-a-date-range](http://Stack Overflow) and have tried to implement it but it does not seem to be working for me. I think that the issue maybe in the way that the $exclude array contents.
<?php
/**
* Function will give the day ($day) of the week (say monday) for the next 3 ($interval) months
* current date (as in today) is excluded
* @param int $interval number of months, e.g. 2
* @param $day - expected to be a day of the week, e.g. Monday
* @return object of type DatePeriod
*/
function getRepeatingDays($interval, $day) {
$theDay = 'next '.$day;
$endDate = new DateTime();
$interval = new DateInterval("P".$interval."M");
$endDate->add($interval);
return new DatePeriod(
new DateTime(),
DateInterval::createFromDateString($theDay),
$endDate,
DatePeriod::EXCLUDE_START_DATE
);
}
// $dateList is a call to get a list of mondays for the next 2 months
$dateList = getRepeatingDays("2", "monday");
// $exclude is an array of dates that are to be excluded from the results given by $dateList
$exclude = array(
new DateTime('6/17/19'),
new DateTime('8/7/19'),
);
// iterate over $dateList and remove the excluded dates. Output the non-excluded dates
foreach($dateList as $newDate){
if(!in_array($newDate, $exclude)) {
//add to $output the date string as Monday, 03 June 2019 and add a html line break
$output.= $newDate->format("l, d F Y")."<br>";
}
}
// output a list of dates
return $output;
So my issues are:
- how to exclude specific dates from a php DatePeriod object output
- how to manipulate the output from a MIGX TV list of dates
Looking forward to your help. Many thanks.
This was a really interesting problem. I couldn’t make your method work, but here’s another approach that I think uses more readable code and has the holidays built in for any year.
I tested it and at least it works for memorial day. 
* @param string $curYear - current year, e.g. "2019"
* @return array - array of holiday timestamps
*/
function getHolidays($curYear) {
$holidays = array();
$holidays[] = strtotime("january $curYear third monday"); //marthin luther king jr.day
$holidays[] = strtotime("february $curYear third monday"); //presidents day
$holidays[] = strtotime(easter_date($curYear)); // easter
$MDay = date('Y-m-d', strtotime("may $curYear first monday")); // memorial day (set below)
$eMDay = explode("-", $MDay);
$year = $eMDay[0];
$month = $eMDay[1];
$day = $eMDay[2];
while ($day <= 31) {
$day = $day + 7;
}
if ($day > 31) {
$day = $day - 7;
}
$holidays[] = strtotime($year . '-' . $month . '-' . $day); // memorial day
$holidays[] = strtotime("september $curYear first monday"); //labor day
$holidays[] = strtotime("october $curYear third monday"); //columbus day
$TH = date('Y-m-d', strtotime("november $curYear first thursday")); // thanks giving (set below)
$eTH = explode("-", $TH);
$year = $eTH[0];
$month = $eTH[1];
$day = $eTH[2];
while ($day <= 30) {
$day = $day + 7;
}
if ($day > 30) //watch out for the days in the month November only have 30
{
$day = $day - 7;
}
$holidays[] = strtotime($year . '-' . $month . '-' . $day); // Thanksgiving
return $holidays;
}
/**
* @param int $t - timestamp
* @param $holidays - array of holiday timestamps
* @return bool - true for holidays or false
*/
function isHoliday($t, $holidays) {
return (in_array($t, $holidays));
}
$curYear = date("Y");//current year
$holidays = getHolidays($curYear);
$weekdayNames = array('Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday');
$output = "";
/* Get day of year */
$today = date('z');
$output .= "\n<br>Today is day# " . $today;
/* $weekdays will be an array of upcoming weekdays that are not holidays */
$weekdays = array();
for ($days=$today; $days < (int) $today + 20; $days++) {
/* Get timestamp for given day */
$timestamp = strtotime("January 1st +" . ($days) . " days");
/* If $timestamp is non-holiday weekday, add it to the $weekdays array */
if (in_array(strftime("%A",$timestamp), $weekdayNames)) {
if (! isHoliday($timestamp, $holidays)) {
$weekdays[] = $timestamp;
}
}
}
/* Display the list of non-holiday weekdays */
foreach ($weekdays as $weekday) {
$output .= "\n<br>" . strftime("%A %c", $weekday);
}
return $output;