當前位置: 首頁> 最新文章列表> 使用date_sub 函數減去工作日:如何避免週末

使用date_sub 函數減去工作日:如何避免週末

gitbox 2025-05-28

為什麼簡單減天數會出錯?

舉個例子,假設今天是周一(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(週五),看似正確。但如果起始日期是周一,且你減去的工作日數較大,就會包括週六和周日,計算結果就會偏差。


解決方案思路

  1. 循環減少天數:每減少一天,先判斷當天是否為周末(週六或週日)。

  2. 跳過週末:如果當天是周末,則不計入工作日減少數量。

  3. 繼續減至工作日數滿足要求


代碼示例

下面是一個示例函數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減去天數時,可能會包含週末,導致業務邏輯錯誤。

  • 通過循環判斷是否為工作日,並僅在工作日計數遞減,能準確地實現減去工作日的需求。

  • 這方法簡單且高效,適用於多數需要工作日計算的場景。