I realize there is already a review about this here, but it's using strings and stuff rather than date objects.
I'm trying to make a simple function to calculate days from a point in time and return object(s). The days have to follow an ignore list (like weekends and holidays) to calculate a range of days, then consider itself landing on any of those ignore days/dates in the end range, then compensate to skoot the final range if needed.
After trial and error with different methods of doing this (++ iterations mostly), I settled on this function. It seems too heavy though considering (mostly) all it's doing is skipping certain ISO day numbers to do some adds. I am also not sure its working for all cases.
Are there some PHP date hidden secrets that I am missing? Or a way to boil this down? It seems like a feature such as this (skipping day codes) would be baked into PHP DatePeriod() or DateInterval() but sadly its not. How would you approach this, pref without counters/strtotime stuff, and pref without extra classes or libs?
<?php
function getWorkingDaysFrom($from, $amtOfDays) {
$globalDays = 0; // a global addition to $amtOfDays (such as a minimum shipping time of 3 days across all objects)
$amtOfDays = $amtOfDays + $globalDays; // set base amount of days for initial range before calculations applied
$ignore = array('6', '7'); // days of the week to ignore (weekends are 6 & 7) in ISO-8061
$holidays = array('*-06-13', '*-11-23', '*-12-25', '*-01-01', '*-02-29'); // holiday dates (holidays are ignored if they fall into ignore list)
$oneDay = new DateInterval('P1D');
$from = new DateTime($from);
$to = new DateTime();
$to->add(new DateInterval('P' . $amtOfDays . 'D'));
foreach(new DatePeriod($from, $oneDay, $to) as $day) {
if (in_array($day->format('N'), $ignore)) {
$to->modify('+1 day');
} elseif (in_array($day->format('*-m-d'), $holidays)) {
$to->modify('+1 day');
}
while (in_array($to->format('N'), $ignore) || (!in_array($to->format('N'), $ignore) && in_array($to->format('*-m-d'), $holidays))) {
$to->modify('+1 day');
}
}
return $to;
}
getWorkingDaysFrom('now', 20);
?>
Thanks for your time and insights.