如何用DateTime生成空闲日期数组?Laravel9课程调度开发求助
问题分析
你的代码存在几个关键问题:
$interval的注释错误,P1D是每天的间隔,不是每月;$seasons定义的是预订区间的起止日期,但原代码用in_array判断单个日期是否在数组中,只会跳过2023-02-01和2023-02-13这两天,而非整个区间;- 循环内重复计算每月的起止日期,逻辑冗余,且没有实现将日期添加到对应子数组的核心逻辑。
修正后的代码
// 初始化空闲时间数组,第一个子数组存预订前的日期 $free_time_frame = [[]]; // 总时间范围 $start = new DateTime("2023-01-01"); $end = new DateTime("2023-12-31"); $interval = new DateInterval("P1D"); $period = new DatePeriod($start, $interval, $end->modify('+1 day')); // 包含结束日期 // 定义已预订的时间区间 $bookedStart = new DateTime("2023-02-01"); $bookedEnd = new DateTime("2023-02-13"); $hasSwitched = false; // 标记是否已切换到预订后的子数组 foreach ($period as $date) { $currentDateStr = $date->format("Y-m-d"); // 判断当前日期是否在已预订区间内 if ($date >= $bookedStart && $date <= $bookedEnd) { // 仅在第一次进入预订区间时,新建子数组存预订后的日期 if (!$hasSwitched) { $free_time_frame[] = []; $hasSwitched = true; } continue; // 跳过预订日期 } // 获取当前要添加的子数组索引(0是预订前,1是预订后) $targetIndex = $hasSwitched ? 1 : 0; $free_time_frame[$targetIndex][] = $currentDateStr; } // 移除可能的空数组(比如如果预订区间在全年最开始或最后) $free_time_frame = array_filter($free_time_frame); // 输出结果 print_r($free_time_frame);
代码说明
- 预订区间判断:用
DateTime对象直接比较日期,覆盖整个2023-02-01至2023-02-13的区间,而非单个日期; - 子数组切换:通过
$hasSwitched标记,仅在第一次进入预订区间时创建新的子数组,避免重复创建; - 包含结束日期:创建
DatePeriod时给$end加了一天,确保2023-12-31被包含在内; - 空数组过滤:最后用
array_filter移除可能的空数组,避免结果中出现无用的空元素。
运行后会生成你预期的结构:第一个子数组是2023-01-01到2023-01-31的所有日期,第二个子数组是2023-02-14到2023-12-31的所有日期。
内容的提问来源于stack exchange,提问作者user20718909
相关产品推荐
相关产品推荐

