无需Moment.js检测时间段冲突:修复现有代码问题
时间段冲突检测代码修复
问题描述
需要实现一个函数,判断选中的时间段是否与给定的时间段列表存在冲突:若冲突返回true,否则返回false。原代码无法覆盖所有冲突场景,导致部分测试用例结果错误。
原代码:
return list.some(item => { if (new Date(item.startDate).getTime() <= new Date(selectedStartDate).getTime() && new Date(item.endDate).getTime() > new Date(selectedStartDate).getTime()) { return true; } if (new Date(item.startDate).getTime() < new Date(selectedEndDate).getTime() && new Date(item.endDate).getTime() > new Date(selectedEndDate).getTime()) { return true; } return false })
测试用时间段列表:
const list = [ { startDate: new Date('2022-10-10T11:00:00'), endDate: new Date('2022-10-10T11:30:00') }, { startDate: new Date('2022-10-10T12:00:00'), endDate: new Date('2022-10-10T13:00:00') } ]
测试用例:
- 选中时间段覆盖两个列表项:
const selectedSlot = { startDate: new Date('2022-10-10T10:30:00'), endDate: new Date('2022-10-10T12:30:00') }
- 选中时间段结束时间与列表项结束时间重合:
const selectedSlot = { startDate: new Date('2022-10-10T10:30:00'), endDate: new Date('2022-10-10T11:30:00') }
- 选中时间段与列表完全不重叠:
const selectedSlot = { startDate: new Date('2022-10-11T10:30:00'), endDate: new Date('2022-10-11T11:30:00') }
问题分析
原代码仅覆盖了两种部分重叠场景,遗漏了以下关键情况:
- 选中时间段完全包含列表中的某个时间段
- 选中时间段的结束时间与列表项的结束时间完全重合(或开始时间与列表项开始时间重合)的场景
更高效的逻辑是:先判断两个时间段完全不冲突的情况,再取反得到冲突结果。完全不冲突的条件是:
- 选中时间段的结束时间 ≤ 列表项的开始时间(选中项在列表项之前)
- 选中时间段的开始时间 ≥ 列表项的结束时间(选中项在列表项之后)
只要不满足以上两种情况,就说明存在冲突。
修复后的代码
function hasTimeConflict(list, selectedSlot) { // 提前转换时间戳,避免重复创建Date对象 const selectedStart = selectedSlot.startDate.getTime(); const selectedEnd = selectedSlot.endDate.getTime(); return list.some(item => { const itemStart = item.startDate.getTime(); const itemEnd = item.endDate.getTime(); // 完全不冲突的两种情况,取反就是冲突 return !(selectedEnd <= itemStart || selectedStart >= itemEnd); }); }
测试验证
- 测试用例1:
hasTimeConflict(list, selectedSlot)返回true(与两个列表项均冲突) - 测试用例2:
hasTimeConflict(list, selectedSlot)返回true(与第一个列表项结束时间重合,判定为冲突) - 测试用例3:
hasTimeConflict(list, selectedSlot)返回false(完全不重叠)
内容的提问来源于stack exchange,提问作者Indraraj26
相关产品推荐
相关产品推荐

