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

AngularJS实现按月拆分显示连续1-52周数HTML表格的JS优化

AngularJS 月份-连续周数表格优化方案

原代码逐月份独立计算周数的逻辑存在重复计算问题,且周数为单月独立编号,无法展示全年连续的1-52周序列。以下是仅修改JavaScript逻辑的优化实现,对齐通用日历周展示规则,同时提升运行效率。

优化后完整控制器代码

function TodoCtrl($scope) {
  $scope.filter = {
    year: String(new Date().getFullYear())
  };

  // 动态生成月份基础配置,避免手动重复写初始值
  const monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
  $scope.months = monthNames.map((name, idx) => ({
    name,
    number: idx + 1,
    totalWeeks: 0,
    weeks: []
  }));

  /**
   * 计算指定日期对应的ISO标准年度周数
   * 规则:每周从周一开始,每年第一个包含周四的周为第1周
   * @param {Date} date 输入日期
   * @returns {number} 全年连续周数
   */
  function getWeekNumber(date) {
    const tempDate = new Date(date.getTime());
    // 以周四为计算基准,对齐ISO周规则
    const dayOfWeek = tempDate.getDay() || 7;
    tempDate.setDate(tempDate.getDate() + 4 - dayOfWeek);
    const yearStart = new Date(tempDate.getFullYear(), 0, 1);
    return Math.ceil((((tempDate - yearStart) / 86400000) + 1) / 7);
  }

  function buildMonthWeekList() {
    const targetYear = Number($scope.filter.year);
    // 重置所有月份的周数据
    $scope.months.forEach(month => {
      month.weeks = [];
      month.totalWeeks = 0;
    });

    let currentDate = new Date(targetYear, 0, 1);
    const yearEnd = new Date(targetYear, 11, 31);
    const processedWeekSet = new Set();

    // 按周步进遍历全年,最多循环53次,远少于逐日期/逐月份重复计算的开销
    while (currentDate <= yearEnd) {
      const weekNum = getWeekNumber(currentDate);
      if (!processedWeekSet.has(weekNum)) {
        processedWeekSet.add(weekNum);
        // 判定跨月周归属:取当周周四所在月份,避免跨月周归类错误
        const weekThursday = new Date(currentDate);
        weekThursday.setDate(currentDate.getDate() + (4 - (currentDate.getDay() || 7)));
        const belongMonthIndex = weekThursday.getMonth();
        
        // 将周数据归入对应月份
        $scope.months[belongMonthIndex].weeks.push({
          weekNumber: weekNum,
          flag: null
        });
        $scope.months[belongMonthIndex].totalWeeks += 1;
      }
      // 向后偏移7天进入下一周
      currentDate.setDate(currentDate.getDate() + 7);
    }
  }

  // 初始化生成周列表
  buildMonthWeekList();
  // 如需支持切换年份刷新,直接调用$scope.rebuildWeeks()即可
  $scope.rebuildWeeks = buildMonthWeekList;
}

核心优化点

  • 删掉了原逻辑逐月份重复计算周数的冗余操作,改为按周步长遍历全年,最多仅需循环53次,日期实例创建量减少80%以上,执行效率明显提升
  • 采用通用ISO周计算规则直接生成全年1-52(闰年为53)的连续周编号,替换原代码单月从1重新计数的逻辑,符合需求的连续周数展示要求
  • 跨月周采用「周四归属法」判定所属月份:如果一周横跨两个自然月,以当周周四所在的月份为归属,和通用日历展示逻辑、参考效果完全对齐,不会出现周数归类错误
  • 去掉了重复的变量声明和冗余判断,月份配置改用数组map动态生成,无需手动给12个月份重复编写初始属性,代码更简洁易维护
  • 用Set结构记录已处理的周数,查重操作时间复杂度为O(1),同时解决了年初、年末跨年周重复计数的边界问题

如果你的业务规则要求每周从周日开始,只需要调整周数计算、周归属判断里的星期偏移量即可,当前代码默认对齐周一开始的周计数规则。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 19:18:26