You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Carbon PHP计算日期时如何正确跳过连续节假日

问题分析

原代码的核心问题有两个:

  • 循环次数被固定为$count,遇到多个连续节假日时,没法额外增加跳过次数
  • 检查的是原始日期加上$i个工作日后的日期,不是当前计算过程中已经调整过的日期,逻辑完全错位,导致新增的节假日没被检测到

比如你测试的场景:2023-06-16(周五)加1个工作日本来是6-19(周一),但6-19和6-20都是节假日,原代码只循环1次,只检查了6-19,加了一天到6-20,但没继续检查6-20是不是节假日,所以停在了错误的日期。

修正方案

换一种更可靠的思路:逐步推进日期,每一步都确认当前日期是有效工作日(非周末+非节假日),直到累计完成$count个有效工作日的添加。

修正后的代码:

function daySkip($date, $count = 0) {
    $holidays = ["2023-06-19", "2023-06-20"];
    // 将节假日转为键为日期的关联数组,提升查询效率
    $holidayMap = collect($holidays)->flip();

    $currentDate = Carbon::parse($date);
    $validWorkdaysAdded = 0;

    while ($validWorkdaysAdded < $count) {
        $currentDate->addDay();
        // 跳过周末和节假日,不计入有效工作日
        if ($currentDate->isWeekend() || isset($holidayMap[$currentDate->toDateString()])) {
            continue;
        }
        $validWorkdaysAdded++;
    }

    return $currentDate->format("d-m-Y");
}
代码说明
  • 用collect($holidays)->flip()转换数组,把日期作为键,后续用isset查询比in_array效率更高,节假日数量多的时候差异更明显
  • 循环逻辑改为:每次推进一天,只有当天是非周末且非节假日时,才算完成一个有效工作日的计数
  • 不管有多少连续节假日,都会持续跳过,直到凑够$count个有效工作日

测试你的场景:

$input = "2023-06-16";
$addday = daySkip($input, 1);
// 输出 21-06-2023,符合预期

如果你偏好先加工作日再调整的思路,也可以用下面的写法,核心是循环检查当前日期是否在节假日列表中,直到跳出所有节假日:

function daySkip($date, $count = 0) {
    $holidays = ["2023-06-19", "2023-06-20"];
    $holidayMap = collect($holidays)->flip();

    $currentDate = Carbon::parse($date)->addWeekdays($count);

    // 循环跳过所有连续的节假日(同时自动跳过周末)
    while (isset($holidayMap[$currentDate->toDateString()]) || $currentDate->isWeekend()) {
        $currentDate->addDay();
    }

    return $currentDate->format("d-m-Y");
}

内容的提问来源于stack exchange,提问作者Bertho Joris

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 05:25:28