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.
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 it's 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.
$oneDay
with$to->add();
rather than$to->modify('+1 day');
in this paste right :) \$\endgroup\$