如何从日期范围数组获取最早起始、最晚结束日期并生成每日序列?
解决方法:获取最早开始日期、最晚结束日期并生成日期列表
其实不用先排序整个数组,我们可以一次遍历数组就能同时拿到最早的date_start和最晚的date_end,这样效率更高,之后再用DatePeriod生成日期范围就很简单了。
步骤1:遍历数组,找到最早开始和最晚结束日期
我们可以用DateTime类来处理日期,它比strtotime更灵活可靠:
// 假设你的数组叫 $promotions $promotions = [ [ "id" => "19", "date_start" => "2018-01-15 00:00:00", "date_end" => "2018-01-16 00:00:00", "promo_name" => "Promo 1" ], [ "id" => "18", "date_start" => "2018-01-16 00:00:00", "date_end" => "2018-01-19 00:00:00", "promo_name" => "Promo 2" ] ]; // 初始化最早开始日期为第一个元素的start $earliestStart = new DateTime($promotions[0]['date_start']); // 初始化最晚结束日期为第一个元素的end $latestEnd = new DateTime($promotions[0]['date_end']); foreach ($promotions as $promo) { $currentStart = new DateTime($promo['date_start']); $currentEnd = new DateTime($promo['date_end']); // 更新最早开始日期 if ($currentStart < $earliestStart) { $earliestStart = $currentStart; } // 更新最晚结束日期 if ($currentEnd > $latestEnd) { $latestEnd = $currentEnd; } }
步骤2:用DatePeriod生成每日日期列表
注意:DatePeriod默认是不包含结束日期的,所以我们需要把$latestEnd加一天,这样才能包含最后一天的日期:
// 给结束日期加1天,确保DatePeriod包含最后一天 $endDate = clone $latestEnd; $endDate->modify('+1 day'); // 创建日期周期,间隔为1天 $period = new DatePeriod( $earliestStart, new DateInterval('P1D'), $endDate ); // 遍历周期,收集每日日期 $dailyDates = []; foreach ($period as $date) { // 可以按你需要的格式格式化,比如Y-m-d $dailyDates[] = $date->format('Y-m-d'); } // 打印结果示例 print_r($dailyDates);
运行这段代码后,$dailyDates会得到:
Array ( [0] => 2018-01-15 [1] => 2018-01-16 [2] => 2018-01-17 [3] => 2018-01-18 [4] => 2018-01-19 )
为什么不用排序?
你之前的排序方法确实能拿到最早的date_start,但要找到最晚的date_end,还是得遍历所有元素——毕竟排序只按start排,end的最大值可能在任何位置。一次遍历同时跟踪两个值,时间复杂度是O(n),比排序的O(n log n)更高效哦。
内容的提问来源于stack exchange,提问作者Kyon147
相关产品推荐
相关产品推荐

