PHP隔日配送日期生成跨周逻辑异常修正方案
问题原因
原有逻辑把传入的周配送日列表作为每周固定匹配的星期值,没有做跨周偏移计算,固定周几配送的场景可以正常运行,但隔日配送这类需要保持固定间隔的连续配送场景,跨周后会直接重置到周规则的第一个值(周一)匹配,打断原有配送节奏。
举个例子,传入[0,2,4,6]对应周一、周三、周五、周日的隔日配送(间隔2天),第一周匹配完周日之后,第二周又会从周一开始找配送日,导致周日到下一个配送日仅隔1天,不符合隔日要求,正确的下一个配送日应该是周二。
修正方案
- 完全兼容原有上游入参结构,不需要改前端/上游传值逻辑
- 先对传入的周配送日排序,计算固定配送步长:每日配送步长为1,隔日配送步长为2,每周单次配送步长为7
- 先匹配到起始日期之后的第一个配送日,后续直接按步长顺延生成日期,不再硬绑定每周固定周几,跨周自动延续间隔节奏
修正后完整代码
$sdate = explode('-',$ProductData[$i]['startdate']); // 客户选择的起始日期 $sdates = $sdate[2].'-'.$sdate[1].'-'.$sdate[0]; $array = explode(',',$ProductData[$i]['select_days']); // 周维度配送日配置,0=周一,6=周日 $sday = $ProductData[$i]['select_days']; $delivery = $ProductData[$i]['total_deliveries']; // 总配送次数,如5、10、15次 $tslot = $ProductData[$i]['tslot']; // 配送时间段,如5:00 AM to 7:00 AM $dates = array(); $pol = array(); $date = new DateTime($sdates); // 排序配送日,计算配送间隔步长 sort($array); if (count($array) == 1) { $step = 7; // 每周仅配送1次的场景,固定间隔7天 } else { $step = (int)$array[1] - (int)$array[0]; } // 转换为DateTime->format('N')兼容的星期值格式(1=周一,7=周日) for($ip=0;$ip<count($array);$ip++) { $pol[] = (int)$array[$ip]+1; } // 匹配起始日期之后的第一个配送日 while (count($dates) < 1) { $date->add(new DateInterval('P1D')); if (in_array((int)$date->format('N'), $pol)) { $dates[] = $date->format('Y-m-d'); } } // 按固定步长生成剩余配送日,跨周自动延续节奏 while (count($dates) < $delivery) { $date->add(new DateInterval('P'.$step.'D')); $dates[] = $date->format('Y-m-d'); } $rdate = implode(',',$dates); // 最终生成的配送日期列表
效果验证
传入$array = [0,2,4,6]、起始日为某周周一时,生成的配送序列为:
- 第一周:周三、周五、周日
- 第二周:周二、周四、周六
- 第三周:周一、周三、周五
完全满足跨周后延续隔日节奏、第二周从周二开始匹配的需求。每日配送场景(传入0-6全量周值,步长为1)的运行结果和原有逻辑完全一致,不会影响现有正常业务。
内容的提问来源于stack exchange,提问作者Aaditya
相关产品推荐
相关产品推荐

