如何在两个日期范围内生成周/月/季度/年度格式化字符串列表
解决跨年度日期范围生成周/月/季度/年度字符串列表的问题
我明白你遇到的问题了——当初始日期和结束日期跨年度时,原来的代码因为只基于起始年份计算范围,会出现缺失或错误的字符串。这里有个更可靠的实现方案,借助moment-range插件来遍历日期范围,完美处理跨年场景:
问题背景
需求:基于指定日期范围,生成四个特定格式的字符串列表,分别对应周(格式
W{周数}_{年份})、月(M{月份}_{年份})、季度(Q{季度}_{年份})和年度(Y{年份}_{年份})。现有代码在日期起止同一年时运行正常,但结束日期跨至下一年时生成的列表会出现缺失或错误。
初始实现代码(存在跨年问题)
dateStart = "01-01-2018"; dateEnd = "03-28-2018"; //get list of week strings lowerRange = Math.ceil(moment(dateStart, "MM-DD-YYYY").dayOfYear()/7); upperRange = Math.ceil(moment(dateEnd, "MM-DD-YYYY").dayOfYear()/7); year = moment(dateStart, "MM-DD-YYYY").year(); weekList = [] for (var i = lowerRange; i <= upperRange; i++) { weekList.push('W' + i + '_' + year); } //get list of month strings lowerRange = moment(dateStart, "MM-DD-YYYY").month()+1; upperRange = moment(dateEnd, "MM-DD-YYYY").month()+1; year = moment(dateStart, "MM-DD-YYYY").year(); monthList = [] for (var i = lowerRange; i <= upperRange; i++) { monthList.push('M' + i + '_' + year); } //get list of quarter strings lowerRange = moment(dateStart, "MM-DD-YYYY").quarter(); upperRange = moment(dateEnd, "MM-DD-YYYY").quarter(); year = moment(dateStart, "MM-DD-YYYY").year(); quarterList = [] for (var i = lowerRange; i <= upperRange; i++) { quarterList.push('Q' + i + '_' + year); } //get list of year strings lowerRange = moment(dateStart, "MM-DD-YYYY").year(); upperRange = moment(dateEnd, "MM-DD-YYYY").year(); yearList = [] for (var i = lowerRange; i <= upperRange; i++) { yearList.push('Y' + i + '_' + year); } console.log(weekList); console.log(monthList); console.log(quarterList); console.log(yearList);
优化后的解决方案代码
核心思路是使用moment-range扩展moment.js,通过遍历日期范围内的每个周/月/季度/年度节点,动态获取当前节点的年份和对应周期数,这样不管跨多少个年度都能正确生成列表:
window['moment-range'].extendMoment(moment); weekList = []; monthList = []; quarterList = []; yearList = []; dateStart = "01-01-2018"; dateEnd = "03-28-2019"; dateStart = moment(dateStart, 'MM-DD-YYYY'); dateEnd = moment(dateEnd, 'MM-DD-YYYY'); dateRange = moment.range(dateStart, dateEnd); // 生成周列表 for (let d of dateRange.by('week')) { weekNumber = Math.ceil(d.dayOfYear()/7); year = d.year(); weekList.push('W' + weekNumber + '_' + year); } // 生成月列表 for (let d of dateRange.by('month')) { monthNumber = d.month() + 1; year = d.year(); monthList.push('M' + monthNumber + '_' + year); } // 生成季度列表 for (let d of dateRange.by('quarter')) { quarterNumber = d.quarter(); year = d.year(); quarterList.push('Q' + quarterNumber + '_' + year); } // 生成年度列表 for (let d of dateRange.by('year')) { yearNumber = d.year(); year = d.year(); yearList.push('Y' + yearNumber + '_' + year); } console.log(weekList) console.log(monthList) console.log(quarterList) console.log(yearList)
优化点说明
- 跨年度兼容:每个周期节点(周/月/季/年)都取自身的年份,而非固定起始年份,彻底解决跨年场景下的字符串缺失或错误问题
- 逻辑更直观:通过遍历日期范围的方式生成列表,避免手动计算上下边界的繁琐和潜在错误
- 可扩展性强:如果后续需要添加其他周期类型(如半年度),只需新增一个遍历逻辑即可
内容的提问来源于stack exchange,提问作者Jabb
相关产品推荐
相关产品推荐

