舉個例子,假設今天是周一(2025-05-26),你想減去3個工作日。如果直接用:
$date = new DateTime('2025-05-26');
$date->sub(new DateInterval('P3D')); // 減去3天
echo $date->format('Y-m-d');
得到的結果是2025-05-23(週五),看似正確。但如果起始日期是周一,且你減去的工作日數較大,就會包括週六和周日,計算結果就會偏差。
循環減少天數:每減少一天,先判斷當天是否為周末(週六或週日)。
跳過週末:如果當天是周末,則不計入工作日減少數量。
繼續減至工作日數滿足要求。
下面是一個示例函數subtractWorkingDays ,它從指定日期開始,減去指定數量的工作日,並跳過週末。
function subtractWorkingDays(DateTime $date, int $days): DateTime {
$result = clone $date; // 克隆避免修改原對象
while ($days > 0) {
$result->sub(new DateInterval('P1D')); // 每次減少一天
$weekday = (int)$result->format('N'); // 1 (週一) 到 7 (週日)
if ($weekday < 6) { // 只有週一到周五才算作工作日
$days--;
}
}
return $result;
}
// 使用示例
$startDate = new DateTime('2025-05-26');
$workDaysToSubtract = 3;
$newDate = subtractWorkingDays($startDate, $workDaysToSubtract);
echo $newDate->format('Y-m-d'); // 輸出結果為2025-05-21,正確跳過週末
使用format('N')獲取星期數字,1為周一,7為周日。
只有當天是工作日(1~5)時, $days計數才遞減。
通過循環,確保減去的天數為純粹工作日。
直接使用date_sub減去天數時,可能會包含週末,導致業務邏輯錯誤。
通過循環判斷是否為工作日,並僅在工作日計數遞減,能準確地實現減去工作日的需求。
這方法簡單且高效,適用於多數需要工作日計算的場景。