patternphpMinor
Get Next Working Date, skip weekends and holidays
Viewed 0 times
workingskipnextdategetandholidaysweekends
Problem
The object is to be able to pass some dates (start date, holiday) and the number of days you want to skip. We only want to skip working days, not weekends and holidays.
Just let me know what you'd do different than what I have. The code works, but I was told there are issues with it, but not told what issues they are.
Just let me know what you'd do different than what I have. The code works, but I was told there are issues with it, but not told what issues they are.
function getWDays($startDate,$holiday,$wDays){
$d = new DateTime( $startDate );
$t = $d->getTimestamp();
$h = strtotime($holiday);
// loop for $wDays days
for($i=0; $isetTimestamp($t);
return $d->format( 'Y-m-d' );
}
echo getWDays("2013-08-29","2013-09-02", 3)Solution
- Use full words to express your function's ability so that your code is intuitive to other developers.
- Organize the incoming parameters so that optional values are listed last. Assign a default value to optional parameters so that they can be omitted from function calls.
- It is too limiting to make the "holiday" parameter a string type variable. Because it is possible that multiple holidays might be encountered while incrementing the date, make the parameter an array. Because it is possible that there are no holidays, design your function to work even if the array is empty.
- Use type hinting on your function parameter to make your code clear and easy to maintain.
- I'll demonstrate using a Datetime object as the hero of the process, but
strtotime()will work too.
- Use a classic
for()loop to increment the counter variable.
- Use
modify()to advance the date to the next available weekday.
- Temporarily store the modified date as Y-m-d so that it can be compared in the next step and eventually returned.
- Use a post-loop check to potentially advance the date past a forbidden date (holiday).
- To safeguard the function from breakage when an integer less than 1 is passed as the second parameter, I am using the null coalescing operator to fallback to the starting date. Other developers may instead prefer to throw an exception -- I would support that technique as well.
Code: (Demo)
function getFutureWeekday(
string $startDate,
int $numberOfDays,
array $holidays = []
): string
{
$dt = new DateTime($startDate);
for ($i = 0; $i modify('+1 weekday')->format('Y-m-d');
} while (in_array($date, $holidays));
}
return $date ?? $startDate;
}
echo getFutureWeekday('2022-03-30', 4, ['2022-04-05']);Code Snippets
function getFutureWeekday(
string $startDate,
int $numberOfDays,
array $holidays = []
): string
{
$dt = new DateTime($startDate);
for ($i = 0; $i < $numberOfDays; ++$i) {
do {
$date = $dt->modify('+1 weekday')->format('Y-m-d');
} while (in_array($date, $holidays));
}
return $date ?? $startDate;
}
echo getFutureWeekday('2022-03-30', 4, ['2022-04-05']);Context
StackExchange Code Review Q#30791, answer score: 5
Revisions (0)
No revisions yet.