使用Moment.js收集指定周几日期仅获部分结果,求修正方案
问题:Moment.js 无法获取指定的全部周几日期
我正在使用Moment.js库,尝试把起始日期(当前日期)到结束日期(2022-09-02)之间的所有周一、周二、周三存入result数组,但最终只获取到周一的日期。怀疑问题出在代码中标注***的逻辑部分。
周几数字定义:
- 1 = 周一
- 2 = 周二
- ...
- 7 = 周日
原代码如下:
var start:Moment = moment(); // today var end:Moment = moment('2022-09-02'); days:number[] = [1, 2, 3]; // monday, tuesday, wednesday function getDates(start:Moment, end:Moment, days:number[]) { let result:Moment[] = []; let current:Moment = start.clone(); // *** 问题所在的逻辑部分 *** days.forEach(element => { console.log(element); while (current.day(7 + element).isBefore(end)) { result.push(current.clone()); } }); // *** 问题所在的逻辑部分结束 *** let datesResult:string[] = result.map(m => m.format('YYYY/MM/DD')); console.log(datesResult); } getDates(start, end, days);
当前输出结果:
['2022/08/15', '2022/08/22', '2022/08/29']
解决方案
问题分析
- 复用
current对象导致后续周几无法处理:遍历目标周几时,没有为每个周几重新克隆起始日期,处理完周一后,current已经跳到超出结束日期的时间点,后续处理周二、周三时,isBefore(end)直接返回false,不会进入循环。 - 循环内未递增日期:原逻辑中仅设置了一次目标周几,但没有每周推进日期,不仅会导致漏加日期,还存在死循环风险(若
current始终满足isBefore(end))。
修改后的代码
var start: Moment = moment(); // today var end: Moment = moment('2022-09-02'); const days: number[] = [1, 2, 3]; // 周一、周二、周三 function getDates(start: Moment, end: Moment, days: number[]) { const result: Moment[] = []; days.forEach(day => { // 为每个周几单独克隆起始日期,避免互相影响 let current = start.clone(); // 定位第一个符合条件的目标周几 if (current.day() < day) { current.day(day); // 本周的目标周几 } else { current.day(7 + day); // 下一周的目标周几 } // 循环添加每周的目标周几,直到超过结束日期 while (current.isBefore(end) || current.isSame(end)) { result.push(current.clone()); current.add(7, 'days'); // 每周递进7天 } }); // 格式化日期,可选排序保证时间顺序 const datesResult: string[] = result .map(m => m.format('YYYY/MM/DD')) .sort(); console.log(datesResult); } getDates(start, end, days);
修改说明
- 独立克隆起始日期:每个目标周几的查找都从全新的起始日期克隆开始,避免前一个周几的处理干扰后续逻辑。
- 精准定位首个目标日期:根据当前日期的周几,判断是取本周还是下一周的目标周几,确保不会漏掉起始日期当天或本周内的符合日期。
- 每周递进日期:通过
current.add(7, 'days')让日期每周前进,覆盖所有符合条件的日期,同时避免死循环。 - 包含结束日期:将判断条件改为
current.isBefore(end) || current.isSame(end),如果结束日期刚好是目标周几,也会被加入数组。 - 可选排序:默认按周一、周二、周三分组存储,添加
sort()后可让整个数组按时间顺序排列。
修改后输出示例:
['2022/08/15', '2022/08/16', '2022/08/17', '2022/08/22', '2022/08/23', '2022/08/24', '2022/08/29', '2022/08/30', '2022/08/31']
内容的提问来源于stack exchange,提问作者wnDesconocido
相关产品推荐
相关产品推荐

