举个例子,假设今天是周一(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 减去天数时,可能会包含周末,导致业务逻辑错误。
通过循环判断是否为工作日,并仅在工作日计数递减,能准确地实现减去工作日的需求。
这方法简单且高效,适用于多数需要工作日计算的场景。