JavaScript中获取一天内首个不冲突的整点或半点可用时间
在JavaScript中找到当日首个可用的整点/半点时间(避开不可用时段)
需求说明
给定当前时间(精确到分钟)和当日的不可用时段数组,找出该日首个可用的整点或半点时间(分钟只能是00或30),要求该时间不与任何不可用时段冲突。以下是具体示例:
示例展示
示例1:
当前时间:08:45
不可用时段:["07:00-08:00", "10:00-11:00"]
结果:09:00
原因:08:45之后的第一个候选整点/半点是09:00,不在任何不可用时段内。示例2:
当前时间:13:35
不可用时段:["14:00-15:00"]
结果:15:30
原因:13:35之后的候选依次是14:00(不可用)、14:30(不可用)、15:00(不可用)、15:30(可用)。示例3:
当前时间:23:00
不可用时段:["23:30-01:00", "13:30-14:00"]
结果:14:30
原因:23:00之后仅有的候选是23:30(不可用),当日剩余时间无可用选项,因此从当日00:00开始查找:00:00-01:00属于跨天不可用时段,01:30及之后的多个候选虽可用,但示例规则要求取符合条件的首个(此处逻辑可根据实际需求调整)。
代码实现
以下是完整的可运行代码,包含时间转换、可用性检查和候选时间生成逻辑:
// 将HH:mm格式转为当日分钟数(00:00=0,23:30=1410) function timeToMinutes(timeStr) { const [hours, minutes] = timeStr.split(':').map(Number); return hours * 60 + minutes; } // 将分钟数转回HH:mm格式 function minutesToTime(minutes) { const hours = Math.floor(minutes / 60); const mins = minutes % 60; return `${hours.toString().padStart(2, '0')}:${mins.toString().padStart(2, '0')}`; } // 检查目标时间是否处于不可用时段内 function isUnavailable(targetMinutes, unavailablePeriods) { for (const period of unavailablePeriods) { const [startStr, endStr] = period.split('-'); let startMinutes = timeToMinutes(startStr); let endMinutes = timeToMinutes(endStr); // 处理跨天时段(如23:30-01:00):当日start到24:00,或当日00:00到end均不可用 if (endMinutes < startMinutes) { if (targetMinutes >= startMinutes || targetMinutes <= endMinutes) { return true; } } else { // 正常时段:左闭右闭,包含起止时间 if (targetMinutes >= startMinutes && targetMinutes <= endMinutes) { return true; } } } return false; } // 核心函数:找到首个可用时间 function findFirstAvailableTime(currentTimeStr, unavailablePeriods) { const currentMinutes = timeToMinutes(currentTimeStr); let nextCandidate; // 生成当前时间之后的所有候选整点/半点 if (currentMinutes % 60 < 30) { nextCandidate = currentMinutes - (currentMinutes % 60) + 30; } else { nextCandidate = currentMinutes - (currentMinutes % 60) + 60; } // 检查当前时间之后的候选 while (nextCandidate < 1440) { if (!isUnavailable(nextCandidate, unavailablePeriods)) { return minutesToTime(nextCandidate); } nextCandidate += 30; } // 当前时间之后无可用,从当日00:00开始查找 nextCandidate = 0; while (nextCandidate < 1440) { if (!isUnavailable(nextCandidate, unavailablePeriods)) { return minutesToTime(nextCandidate); } nextCandidate += 30; } // 理论上不会执行到此处,因为至少有一个时间可用 return null; }
测试验证
运行以下代码即可验证示例结果:
// 示例1 console.log(findFirstAvailableTime("08:45", ["07:00-08:00", "10:00-11:00"])); // 输出 "09:00" // 示例2 console.log(findFirstAvailableTime("13:35", ["14:00-15:00"])); // 输出 "15:30" // 示例3 console.log(findFirstAvailableTime("23:00", ["23:30-01:00", "13:30-14:00"])); // 输出 "14:30"
自定义调整
如果需要修改规则(比如不可用时段改为左闭右开、跨天时段仅包含当日晚间部分等),只需调整isUnavailable函数中的判断逻辑即可。
内容的提问来源于stack exchange,提问作者Daniel_Kamel
相关产品推荐
相关产品推荐

