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

如何将指定时间范围集合从另一个时间范围集合中移除?

实现思路

  • 先把所有时间字符串转为时间戳,避免字符串直接比对的格式兼容问题,提升比较效率
  • 遍历第二组xyz的每一个时间范围,和第一组abc的所有待排除时间范围逐一做重叠校验
  • 针对不同重叠场景做对应切割处理:
    • 无重叠:直接保留原xyz时间范围
    • 待排除范围完全覆盖当前xyz范围:直接丢弃该段xyz时间
    • 待排除范围和xyz开头重叠:保留xyz中待排除结束时间到原xyz结束时间的部分
    • 待排除范围和xyz结尾重叠:保留xyz开始时间到待排除开始时间的部分
    • 待排除范围完全在xyz内部:切割为前后两段保留
  • 汇总所有处理后的有效时间范围即为最终结果

JavaScript 实现代码

// 时间字符串转时间戳
function toTimestamp(timeStr) {
  return new Date(timeStr).getTime();
}

function subtractTimeRanges(xyz, abc) {
  let result = JSON.parse(JSON.stringify(xyz));
  // 遍历所有要排除的时间范围
  for (const exclude of abc) {
    const excludeStart = toTimestamp(exclude.start);
    const excludeEnd = toTimestamp(exclude.end);
    const tempResult = [];
    // 逐段处理当前保留的时间
    for (const range of result) {
      const rangeStart = toTimestamp(range.start);
      const rangeEnd = toTimestamp(range.end);
      // 完全不重叠直接保留
      if (excludeEnd <= rangeStart || excludeStart >= rangeEnd) {
        tempResult.push({...range});
        continue;
      }
      // 待排除段完全覆盖当前段,直接丢弃
      if (excludeStart <= rangeStart && excludeEnd >= rangeEnd) {
        continue;
      }
      // 重叠开头,保留后半段
      if (excludeStart <= rangeStart && excludeEnd < rangeEnd) {
        tempResult.push({
          start: new Date(excludeEnd).toISOString().slice(0, 19).replace('T', ' '),
          end: range.end
        });
        continue;
      }
      // 重叠结尾,保留前半段
      if (excludeStart > rangeStart && excludeEnd >= rangeEnd) {
        tempResult.push({
          start: range.start,
          end: new Date(excludeStart).toISOString().slice(0, 19).replace('T', ' ')
        });
        continue;
      }
      // 待排除段在中间,拆为两段
      if (excludeStart > rangeStart && excludeEnd < rangeEnd) {
        tempResult.push({
          start: range.start,
          end: new Date(excludeStart).toISOString().slice(0, 19).replace('T', ' ')
        });
        tempResult.push({
          start: new Date(excludeEnd).toISOString().slice(0, 19).replace('T', ' '),
          end: range.end
        });
      }
    }
    result = tempResult;
  }
  return result;
}

// 测试用例
const abc = [{"start": "2021-11-25 16:30:00", "end": "2021-11-25 17:30:00"}];
const xyz = [
  {"start": "2021-11-25 09:00:00", "end": "2021-11-25 18:00:00"},
  {"start": "2021-11-26 15:00:00", "end": "2021-11-26 19:00:00"}
];
console.log(subtractTimeRanges(xyz, abc));

PHP 实现代码

// 时间字符串转时间戳
function toTimestamp(string $timeStr): int {
    return strtotime($timeStr);
}

function subtractTimeRanges(array $xyz, array $abc): array {
    $result = json_decode(json_encode($xyz), true);
    foreach ($abc as $exclude) {
        $excludeStart = toTimestamp($exclude['start']);
        $excludeEnd = toTimestamp($exclude['end']);
        $tempResult = [];
        foreach ($result as $range) {
            $rangeStart = toTimestamp($range['start']);
            $rangeEnd = toTimestamp($range['end']);
            // 完全不重叠直接保留
            if ($excludeEnd <= $rangeStart || $excludeStart >= $rangeEnd) {
                $tempResult[] = $range;
                continue;
            }
            // 待排除段完全覆盖当前段,直接丢弃
            if ($excludeStart <= $rangeStart && $excludeEnd >= $rangeEnd) {
                continue;
            }
            // 重叠开头,保留后半段
            if ($excludeStart <= $rangeStart && $excludeEnd < $rangeEnd) {
                $tempResult[] = [
                    'start' => date('Y-m-d H:i:s', $excludeEnd),
                    'end' => $range['end']
                ];
                continue;
            }
            // 重叠结尾,保留前半段
            if ($excludeStart > $rangeStart && $excludeEnd >= $rangeEnd) {
                $tempResult[] = [
                    'start' => $range['start'],
                    'end' => date('Y-m-d H:i:s', $excludeStart)
                ];
                continue;
            }
            // 待排除段在中间,拆为两段
            if ($excludeStart > $rangeStart && $excludeEnd < $rangeEnd) {
                $tempResult[] = [
                    'start' => $range['start'],
                    'end' => date('Y-m-d H:i:s', $excludeStart)
                ];
                $tempResult[] = [
                    'start' => date('Y-m-d H:i:s', $excludeEnd),
                    'end' => $range['end']
                ];
            }
        }
        $result = $tempResult;
    }
    return $result;
}

// 测试用例
$abc = [['start' => '2021-11-25 16:30:00', 'end' => '2021-11-25 17:30:00']];
$xyz = [
    ['start' => '2021-11-25 09:00:00', 'end' => '2021-11-25 18:00:00'],
    ['start' => '2021-11-26 15:00:00', 'end' => '2021-11-26 19:00:00']
];
var_dump(subtractTimeRanges($xyz, $abc));

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 13:36:02