You need to enable JavaScript to run this app. 使用Moment.js计算两选定日期覆盖的所有自然月总天数
优惠活动
大模型
产品
解决方案
定价
更多

使用Moment.js计算两选定日期覆盖的所有自然月总天数

原代码核心缺陷
  • 逻辑覆盖不全:仅提取两个输入日期对应月份的天数做简单累加,完全没有设置遍历两个日期跨域区间内所有自然月的流程,只要两个日期之间间隔了整月,就会直接漏算中间月份的天数。
  • 判断逻辑无效:通过两个月份的天数差值判断是否属于同月,这个逻辑本身不成立——比如1月和3月的整月天数都是31天,差值为0,原代码会直接只返回单月的31天,连首尾两个月的累加都做不到,进一步放大了计算错误。
  • 存在无效冗余:代码中夹带了打印当前实时日期天数的调试语句,和实际计算逻辑没有关联。
正确实现方案

核心实现逻辑:

  • 对两个输入日期做归一化处理:统一对齐到当月1号的时间点,彻底消除“具体是当月几号”对月份范围判断的干扰
  • 自动识别两个月份的先后顺序,避免用户传入日期顺序颠倒时计算出错
  • 从最早的月份开始,逐月向后遍历直到最晚的月份,每遍历一个月就取当月整月天数做累加

实现代码:

const getTotalDaysOfCoveredMonths = (selectedDate1, selectedDate2) => {
  // 归一化两个日期到当月1号的时间点,消除具体日的干扰
  const monthOfFirst = moment(selectedDate1).startOf('month')
  const monthOfSecond = moment(selectedDate2).startOf('month')
  // 自动校正日期顺序,兼容用户传入参数颠倒的场景
  const [startMonth, endMonth] = monthOfFirst.unix() <= monthOfSecond.unix()
    ? [monthOfFirst, monthOfSecond]
    : [monthOfSecond, monthOfFirst]

  let totalDays = 0
  let cursor = startMonth.clone()
  // 逐月遍历所有覆盖的自然月
  while (cursor.unix() <= endMonth.unix()) {
    totalDays += cursor.daysInMonth()
    // 游标向后移动一个月
    cursor.add(1, 'month')
  }
  return totalDays
}
场景验证
  • 题目示例测试:输入2021-01-01、2021-03-01,遍历覆盖1月、2月、3月,累加结果为31 + 28 + 31 = 90,完全符合需求预期
  • 同月场景测试:输入同月份的两个任意日期,自动返回对应自然月的整月天数,不会重复计算
  • 跨多年场景测试:比如从2020年12月到2021年2月,会自动遍历3个月份,正确计算31 + 31 + 28的总天数,不会出现漏算

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.04 23:24:04