原生JS实现生成两个日期间年月映射对象的问题求助
问题与解决方案
需求描述
给定两个日期(例如15.05.2010到03.02.2012),生成格式为{'2010': ['May', 'June', ...], ..., '2012': ['January', 'February']}的年月映射对象。
- 约束:仅允许使用原生JavaScript,不可依赖第三方库
- 补充要求:遍历所有涉及的年份,明确每个年份包含的月份
现有尝试代码
已实现年份集合生成,但无法正确为年份匹配对应月份,尝试代码如下:
const startDate = new Date('2005-01-01'); const today = new Date(); // const difference = today.getFullYear() - startFrom.getFullYear(); const years = []; const lastYear = today.getFullYear() - 1; const yearsAndMonths = {}; let startFrom = startDate; // set all the years while (startFrom.setFullYear(startFrom.getFullYear() + 1) < today.setFullYear(lastYear)) { years.push(startFrom.toLocaleDateString('de-AT', { year: 'numeric', })); } startFrom.setFullYear(startDate); while (startFrom.setMonth(startFrom.getMonth() + 1) < today) { const year = startFrom.getFullYear(); const yearIndex = yearsAndMonths.indexOf(year); yearsAndMonths[year].push(startFrom.toLocaleDateString('de-AT', { month: 'long' })); } console.log(yearsAndMonths);
问题分析与修复方案
原代码核心问题:
yearsAndMonths是对象,不存在indexOf方法,直接调用会报错- 未先初始化年份对应的数组,直接
push会触发Cannot read properties of undefined (reading 'push')错误
修复后的完整实现:
// 辅助函数:将dd.mm.yyyy格式转为Date对象 function parseDate(dateStr) { const [day, month, year] = dateStr.split('.'); // 月份是0基索引,需减1 return new Date(year, month - 1, day); } function getYearMonthMap(startDateStr, endDateStr) { const start = parseDate(startDateStr); const end = parseDate(endDateStr); const yearMonthMap = {}; // 复制开始日期,避免修改原对象 const current = new Date(start); while (current <= end) { const year = current.getFullYear().toString(); // 获取英文全称月份 const month = current.toLocaleDateString('en-US', { month: 'long' }); // 年份不存在则初始化数组 if (!yearMonthMap[year]) { yearMonthMap[year] = []; } // 避免重复添加同一月份 if (!yearMonthMap[year].includes(month)) { yearMonthMap[year].push(month); } // 推进一个月 current.setMonth(current.getMonth() + 1); } return yearMonthMap; } // 示例调用 const result = getYearMonthMap('15.05.2010', '03.02.2012'); console.log(result); // 输出:{ '2010': ['May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'], '2011': ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'], '2012': ['January', 'February'] }
关键说明
- 日期解析:针对
dd.mm.yyyy格式拆分后转换为Date对象,适配月份0基索引规则 - 循环遍历:从开始日期逐月推进,直到超过结束日期
- 对象初始化:每次处理月份时,先检查年份是否已在映射中,未存在则创建空数组
- 月份去重:避免因月末跨月操作导致的重复添加问题
- 月份格式:使用
toLocaleDateString('en-US', { month: 'long' })确保获取英文全称月份
内容的提问来源于stack exchange,提问作者Nachtfunke
相关产品推荐
相关产品推荐

