You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

原生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'] }

关键说明

  1. 日期解析:针对dd.mm.yyyy格式拆分后转换为Date对象,适配月份0基索引规则
  2. 循环遍历:从开始日期逐月推进,直到超过结束日期
  3. 对象初始化:每次处理月份时,先检查年份是否已在映射中,未存在则创建空数组
  4. 月份去重:避免因月末跨月操作导致的重复添加问题
  5. 月份格式:使用toLocaleDateString('en-US', { month: 'long' })确保获取英文全称月份

内容的提问来源于stack exchange,提问作者Nachtfunke

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 18:48:24