
本文介绍一种简洁可靠的 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/2022', 5, ['Tue', 'Thu']);
foreach ($result as $item) {
echo "{$item['date']} - {$item['day']}\n";
}✅ 输出结果(符合预期):
08/02/2022 - Tue 10/02/2022 - Thu 15/02/2022 - Tue 17/02/2022 - Thu 22/02/2022 - 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])。
该方法摒弃了复杂的时间间隔计算与嵌套循环,回归问题本质——线性扫描 + 条件收集,是解决此类“按星期几生成有序日期序列”需求的推荐实践。










