信息发布→ 登录 注册 退出

计算指定工作日的未来 N 个日期

发布时间:2026-01-10

点击量:

本文介绍一种简洁可靠的 php 方法,用于从起始日期开始,按顺序获取指定星期几(如周二、周四)的接下来 n 个日期,支持任意组合与数量,代码清晰、逻辑直观、易于扩展。

在日常开发中,我们常需生成特定星期几的未来日期序列(例如:每周二和周四共 5 次会议安排)。核心难点在于:不能简单按周循环(易跳过或重复),而应逐日推进、动态匹配目标星期几,并严格按时间顺序累积结果

以下是一个高效、可读性强且鲁棒的实现方案:

function getNextWeekdayDates(string $startDate, int $count, array $targetDays): array
{
    // 支持英文全称或缩写(如 'Tuesday'/'Tue', 'Thursday'/'Thu')
    $normalize = function($day) {
        $map = [
            'mon' => 'Mon', 'monday' => 'Mon',
            'tue' => 'Tue', 'tuesday' => 'Tue',
            'wed' => 'Wed', 'wednesday' => 'Wed',
            'thu' => 'Thu', 'thursday' => 'Thu',
            'fri' => 'Fri', 'friday' => 'Fri',
            'sat' => 'Sat', 'saturday' => 'Sat',
            'sun' => 'Sun', 'sunday' => 'Sun'
        ];
        return $map[strtolower(trim($day))] ?? strtoupper(substr(trim($day), 0, 3));
    };

    $weekDays = array_map($normalize, $targetDays);
    $dates = [];
    $date = date_create($startDate);

    if (!$date) {
        throw new InvalidArgumentException("Invalid start date: {$startDate}");
    }

    while ($count > 0 && $date !== false) {
        $dayOfWeek = $date->format('D');
        if (in_array($dayOfWeek, $weekDays)) {
            $dates[] = [
                'date' => $date->format('d/m/Y'),
                'day'  => $dayOfWeek
            ];
            $count--;
        }
        $date->modify('+1 day');
    }

    return $dates;
}

// 使用示例
$result = getNextWeekdayDates('02/08/2025', 5, ['Tue', 'Thu']);
foreach ($result as $item) {
    echo "{$item['date']} - {$item['day']}\n";
}

输出结果(符合预期):

08/02/2025 - Tue  
10/02/2025 - Thu  
15/02/2025 - Tue  
17/02/2025 - Thu  
22/02/2025 - Tue  

关键优势说明:

  • 逐日推进,保证时序准确:避免因“跳周”导致遗漏(如起始日为周四,直接加 7 天会跳过当周周二);
  • 灵活输入支持:兼容 Tue/Thu、Tuesday/Thursday 等多种写法;
  • 强健性处理:内置日期校验与异常提示;
  • 结构化返回:同时提供格式化日期与星期简称,便于前端展示或进一步处理。

注意事项:

  • 输入日期格式需被 date_create() 识别(推荐 d/m/Y 或 Y-m-d);若使用 m/d/Y(美式),请确保系统区域设置或显式指定 DateTime::createFromFormat();
  • $targetDays 中的值不区分大小写,但建议统一使用首字母大写的缩写('Tue', 'Thu')以提高可读性;
  • 若需 ISO 标准星期编号(周一=1),可改用 $date->format('N') 并匹配数字数组(如 [2,4])。

该方法摒弃了复杂的时间间隔计算与嵌套循环,回归问题本质——线性扫描 + 条件收集,是解决此类“按星期几生成有序日期序列”需求的推荐实践。

标签:# php  # 前端  # date  # format  # 循环  # 跳过  # 是一个  # 英文  # 此类  # 而应  # 结构化  # 首字母  # 日为  # 等多种  # 周周  
在线客服
服务热线

服务热线

4008888355

微信咨询
二维码
返回顶部
×二维码

截屏,微信识别二维码

打开微信

微信号已复制,请打开微信添加咨询详情!