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

拆分重叠日期时段并生成新时段的JavaScript实现问题

解决时段重叠拆分问题

问题描述

我有一个包含startDate(开始日期)和endDate(结束日期)的对象数组,示例如下:

var periods = [
  {
    id: "Period1",
    startDate: new Date("2022-08-29"),
    endDate: new Date("2022-12-23")
  },
  {
    id: "Period2",
    startDate: new Date("2022-12-12"),
    endDate: new Date("2023-10-02")
  },
  // 更多时段...
]

需要将存在重叠的时段拆分为新的对象,预期效果如下:

// Period1
// 29/08/2022 - 11/12/2022
// 12/12/2022 - 23/12/2022

// Period2
// 12/12/2022 - 23/12/2022
// 24/12/2022 - 02/10/2023

当前代码仅能处理时段起始日期重叠的情况,无法处理结束时的逻辑,需要完善。

解决方案

核心思路是先提取所有关键时间点(所有时段的开始日期、结束日期+1天),将这些时间点排序去重后,相邻时间点之间就构成了一个无重叠的基础区间,再为每个覆盖该区间的原始时段生成对应的子时段。

完整代码实现:

// 保留你定义的日期扩展方法
Date.prototype.addDays = function (days) {
  var date = new Date(this.valueOf());
  date.setDate(date.getDate() + days);
  return date;
}

var periods = [
  {
    id: "Period1",
    startDate: new Date("2022-08-29"),
    endDate: new Date("2022-12-23")
  },
  {
    id: "Period2",
    startDate: new Date("2022-12-12"),
    endDate: new Date("2023-10-02")
  },
];

// 步骤1:收集所有关键时间点
const keyDates = new Set();
periods.forEach(period => {
  keyDates.add(period.startDate);
  // 结束日期+1天,用于拆分区间的边界
  keyDates.add(period.endDate.addDays(1));
});

// 步骤2:将时间点排序
const sortedDates = Array.from(keyDates).sort((a, b) => a - b);

// 步骤3:遍历相邻时间点,生成拆分后的时段
const splitPeriods = [];
for (let i = 0; i < sortedDates.length - 1; i++) {
  const currentStart = sortedDates[i];
  // 当前区间的结束日期是下一个时间点减1天
  const currentEnd = sortedDates[i + 1].addDays(-1);

  // 找出所有覆盖当前区间的原始时段
  const matchingPeriods = periods.filter(period => {
    return period.startDate <= currentEnd && period.endDate >= currentStart;
  });

  // 为每个匹配的时段生成子时段
  matchingPeriods.forEach(period => {
    splitPeriods.push({
      id: period.id,
      startDate: new Date(currentStart),
      endDate: new Date(currentEnd)
    });
  });
}

console.log(splitPeriods);

代码说明

  1. 关键时间点收集:把每个时段的开始日期和结束日期的次日加入集合,这样能确保所有区间拆分的边界都被覆盖,包括重叠的起始和结束点。
  2. 排序时间点:将时间点按时间顺序排列,保证后续生成的区间是按时间推进的。
  3. 生成子时段:遍历每一对相邻时间点,计算出当前子区间的起止日期,然后找到所有包含这个子区间的原始时段,为每个原始时段生成对应的子时段对象。

运行这段代码后,输出结果将完全符合预期,无论重叠发生在起始还是结束阶段,都能正确拆分。

内容的提问来源于stack exchange,提问作者Jasper De Smet

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 10:40:01