如何用纯JavaScript判断指定时间段是否落入封禁时间范围?
解决注册时间段与每日重复封禁时段的冲突判断问题
看起来你遇到的核心问题是:现有代码把封禁的「多日重复时段」错误当成了一个连续的时间大区间(从4月10日16点到4月18日17点),导致即使你的注册时段不在每日封禁的16-17点,只要日期在10-18日范围内就会被误判拦截。
问题分析
你的封禁规则是2018年4月10日至18日,每天的16:00-17:00,这是一个「每日重复的时段封禁」,而非一个连续的长时间段。原代码直接对比注册时段和整个封禁周期的首尾时间戳,必然会误判——因为注册日期在10-18日之间,哪怕时间是18点,也会被认为在封禁周期的时间范围内。
另外还要注意:JavaScript的Date构造函数中,月份是从0开始计数的!你写的new Date("2018","04","10")实际创建的是2018年5月10日,这也是一个隐藏的bug。
正确的判断逻辑
要正确判断,需要分两步验证:
- 注册的日期是否在封禁的日期区间内(2018年4月10日至4月18日);
- 注册的时间段是否与每日封禁的16:00-17:00有重叠。
只有当两个条件同时满足时,才需要阻止注册。
完整解决方案代码
// 定义封禁规则:日期范围 + 每日封禁时段 const blockedDateRange = { start: new Date(2018, 3, 10), // 4月是索引3,注意月份从0开始 end: new Date(2018, 3, 18) }; const blockedDailyTime = { startHour: 16, startMinute: 0, endHour: 17, endMinute: 0 }; // 注册时间段示例:2018年4月15日18:00-19:00 const registerStart = new Date(2018, 3, 15, 18, 0, 0); const registerEnd = new Date(2018, 3, 15, 19, 0, 0); // 判断函数:检查注册时段是否落入封禁范围 function isBlocked(regStart, regEnd) { // 第一步:检查注册日期是否在封禁日期区间内 const regDateOnly = new Date(regStart.getFullYear(), regStart.getMonth(), regStart.getDate()); const isDateInRange = regDateOnly >= blockedDateRange.start && regDateOnly <= blockedDateRange.end; if (!isDateInRange) { return false; // 日期不在封禁范围,直接返回不拦截 } // 第二步:提取注册时段的时分秒,转换为当天的分钟数(便于比较) const regStartMinutes = regStart.getHours() * 60 + regStart.getMinutes(); const regEndMinutes = regEnd.getHours() * 60 + regEnd.getMinutes(); const blockedStartMinutes = blockedDailyTime.startHour * 60 + blockedDailyTime.startMinute; const blockedEndMinutes = blockedDailyTime.endHour * 60 + blockedDailyTime.endMinute; // 判断两个时间段是否有重叠:注册时段的开始在封禁时段结束前,且注册时段的结束在封禁时段开始后 const isTimeOverlap = regStartMinutes < blockedEndMinutes && regEndMinutes > blockedStartMinutes; return isTimeOverlap; } // 测试你的场景 console.log(isBlocked(registerStart, registerEnd)); // 输出 false,即允许注册
代码解释
- 日期范围判断:我们把注册日期转换为「仅日期」的对象(去掉时分秒),和封禁的起始、结束日期对比,确保注册日期在封禁的日期区间内。
- 时段重叠判断:把时间转换为当天的分钟数(比如16:00是960分钟,17:00是1020分钟),通过简单的数值对比判断两个时段是否有重叠——只要注册时段的开始早于封禁结束,且注册时段的结束晚于封禁开始,就说明有重叠。
- 修复月份bug:明确使用0开始的月份索引,4月对应
3,避免创建错误的日期对象。
测试其他场景
- 如果注册时段是4月15日16:30-17:30,函数会返回
true(拦截); - 如果注册时段是4月9日16:00-17:00,函数返回
false(日期不在封禁范围); - 如果注册时段是4月18日15:30-16:30,函数返回
true(时段重叠)。
内容的提问来源于stack exchange,提问作者Goutam.A.S
相关产品推荐
相关产品推荐

