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

如何计算ISO标准下日期区间内各周的实际天数?

修正ISO周天数计算的moment.js代码

原代码存在几个核心问题:

  • weekEnd的计算逻辑完全错误,不该基于全局endDate叠加周数,应取当前ISO周的实际结束日期
  • daysInweek直接用全局endDate减去weekStart,导致计算的是从当前周起始到全局结束的总天数,而非该周内的有效天数
  • 循环的weeknum计算方式不准确,易导致多循环或少循环

以下是修正后的代码,能正确计算每个ISO周在起始/结束日期范围内的天数:

const startDate = moment(this.chartData.startDate);
const endDate = moment(this.chartData.endDate);

// 从起始日期所在的ISO周开始,遍历到结束日期所在的ISO周
let currentWeekStart = moment(startDate).isoWeekStart(); // 获取当前ISO周的周一(ISO标准周起始为周一)
const endWeekStart = moment(endDate).isoWeekStart();

this.weeks = [];

do {
  // 确定当前周的实际起始日:首周取全局startDate和ISO周起始的较大值
  const actualWeekStart = currentWeekStart.isBefore(startDate) ? moment(startDate) : moment(currentWeekStart);
  // 确定当前周的实际结束日:尾周取ISO周结束(周日)和全局endDate的较小值
  const currentWeekEnd = moment(currentWeekStart).isoWeekEnd();
  const actualWeekEnd = currentWeekEnd.isAfter(endDate) ? moment(endDate) : currentWeekEnd;
  
  // 计算该周的天数:diff返回间隔天数,加1包含首尾日期
  const daysInWeek = actualWeekEnd.diff(actualWeekStart, 'days') + 1;
  const weekNumber = currentWeekStart.isoWeek();
  // 新增周所属年份,解决跨年周的归属混淆(比如2023年1月1日属于2022年第52周)
  const weekYear = currentWeekStart.isoWeekYear();

  this.weeks.push({
    weekYear: weekYear,
    weekNumber: weekNumber,
    weekDays: daysInWeek
  });

  // 移动到下一个ISO周的起始
  currentWeekStart.add(1, 'weeks');
} while (currentWeekStart.isSameOrBefore(endWeekStart));

console.log(this.weeks);

关键修正点说明:

  • 用isoWeekStart()和isoWeekEnd()严格遵循ISO标准获取周的起止日期(周一到周日)
  • 对每个周的实际起止做边界判断,确保只统计用户选择日期范围内的天数
  • 循环逻辑改为基于ISO周的起止遍历,确保覆盖所有涉及的周
  • 新增weekYear字段,避免跨年周的周数归属歧义

测试用例验证(以2023年1月1日为起始,2023年1月3日为结束):

  • 2022年第52周:1天(1月1日)
  • 2023年第1周:2天(1月2日、1月3日)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 21:39:36