如何修改脚本实现基于滚动双周统计两日期间特定配送日数量?
解决方案
1. 调整规则配置结构
把原来的单一星期几数组,改成包含周期规则的对象数组,每个对象描述一条配送规则:
day: 目标星期几(0=周日,1=周一,…,6=周六)cycle: 周期类型,可选'weekly'(每周)或'biweekly'(双周)offset: 双周规则专用,0或1,表示在双周周期的第0/1个周执行(起始日所在的双周为第0周期)
比如你需要的「每周一、隔周周五」(假设起始日所在双周的周五不执行,下一个双周的周五执行,offset=1),配置如下:
var scheduleRules = [ { day: 1, cycle: 'weekly' }, // 每周一 { day: 5, cycle: 'biweekly', offset: 1 } // 隔周周五(从起始日开始的第1、3...个双周执行) ];
2. 核心统计函数实现
保留原有的parseDate函数处理英国格式日期,新增支持双周规则的统计函数:
var date0 = "01/02/2021"; // 起始日期(双周周期的起点) var date1 = "31/01/2022"; var scheduleRules = [ { day: 1, cycle: 'weekly' }, { day: 5, cycle: 'biweekly', offset: 1 } ]; var test = countScheduledDays(scheduleRules, parseDate(date0), parseDate(date1)); alert(test); // 解析dd/mm/yyyy格式日期 function parseDate(str) { var dmy = str.split('/'); return new Date(+dmy[2], dmy[1] - 1, +dmy[0]); } // 统计符合调度规则的天数 function countScheduledDays(rules, fromDate, toDate) { var total = 0; const cycleStartTimestamp = fromDate.getTime(); const dayMs = 24 * 3600 * 1000; const weekMs = 7 * dayMs; rules.forEach(rule => { const targetDay = rule.day; // 找到起始日之后第一个符合目标星期几的日期 let currentDate = new Date(fromDate); if (currentDate.getDay() !== targetDay) { const daysToAdd = (targetDay - currentDate.getDay() + 7) % 7; currentDate.setDate(currentDate.getDate() + daysToAdd); } // 遍历所有同星期几的日期,判断是否符合周期规则 while (currentDate <= toDate) { const daysDiff = Math.floor((currentDate.getTime() - cycleStartTimestamp) / dayMs); const weeksDiff = Math.floor(daysDiff / 7); let isValid = false; if (rule.cycle === 'weekly') { isValid = true; } else if (rule.cycle === 'biweekly') { // 判断当前周在双周周期内的偏移(0或1)是否匹配规则 const cycleWeekOffset = weeksDiff % 2; isValid = cycleWeekOffset === rule.offset; } if (isValid) total++; // 跳到下一个同星期几的日期 currentDate.setDate(currentDate.getDate() + 7); } }); return total; }
3. 关键逻辑说明
- 双周周期匹配:以起始日为双周周期起点,通过计算当前日期与起始日的周数差,取奇偶性判断是否属于规则指定的双周区间,和
offset匹配则计数。 - 混合规则兼容:遍历每条规则单独统计,再累加总数,同时支持周度、双周规则共存。
- 边界处理:自动定位起始日之后第一个符合目标星期几的日期,避免错误计数起始日之前的日期。
4. 自定义调整
如果需要双周周期从起始日所在的完整周开始(比如起始日是周三,双周周期从当周周一算起),可以修改cycleStartTimestamp的计算方式:
// 计算起始日所在周的周一(周一为一周起始) const cycleStartTimestamp = new Date(fromDate); const dayOfWeek = cycleStartTimestamp.getDay(); const daysToMonday = (dayOfWeek === 0 ? 6 : dayOfWeek - 1); // 周日到周一需减6天,其他周几减1 cycleStartTimestamp.setDate(cycleStartTimestamp.getDate() - daysToMonday);
内容的提问来源于stack exchange,提问作者arresteddevelopment
相关产品推荐
相关产品推荐

