

JS判定一个给定的时间区间在哪些时间段范围内
source link: https://www.fly63.com/article/detial/11689
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

扫一扫分享
有这样的一个场景:给定一个时间区间,需要判定这个时间区间在哪些时间段范围内.
比如时间段范围如下:
[["00:00","01:00"],["01:00","02:00"],["02:00","03:00"],["03:00","04:00"],["04:00","05:00"],["05:00","06:00"],["06:00","07:00"],["07:00","08:00"],["08:00","09:00"],["09:00","10:00"],["10:00","11:00"],["11:00","12:00"],["12:00","13:00"],["13:00","14:00"],["14:00","15:00"],["15:00","16:00"],["16:00","17:00"],["17:00","18:00"],["18:00","19:00"],["19:00","20:00"],["20:00","21:00"],["21:00","22:00"],["22:00","23:00"],["23:00","24:00"]]
现在给定一个时间区间 10:15-16:38 ,那么就需要返回 ["10:00","11:00"],["11:00","12:00"],["12:00","13:00"],["13:00","14:00"],["14:00","15:00"],["15:00","16:00"],["16:00","17:00"] 这些时间段范围。
1、常规时间区间判定
假设给定的时间区间为 [st, et],时间段范围为 [t1, t2],那么 [st, et] 在 [t1, t2] 范围内的判定依据有以下几种情况:
- t1 >= st && t2 <= et;
- st >= t1 && st <= t2;
- et >= t1 && et <= t2;
再来看看给定时间区间不在时间段范围内,即 [st, et] 不在 [t1, t2] 范围内的判定依据:
- st < t1 && et < t1;
- st > t2 && et > t2;
从上面的判定依据来看,给定时间区间不在时间段范围内的判定依据更简单,对其取反,即可得到正确的时间段范围,下面给出具体的判定代码:
function judge(startTime, endTime) {
// 生成24小时时间区间,跨度为1小时
let timeArrays = new Array(24).fill(['', '']).map((item, index) => [(index < 10 ? '0' + index : index) + ':00', ((index + 1) < 10 ? '0' + (index + 1) : (index + 1)) + ':00']);
return timeArrays.filter(item => !((compare(item[0], startTime) && compare(item[0], endTime)) || (compare(startTime, item[1]) && compare(endTime, item[1]))));
}
function compare(startTime, endTime) {
// 将时间转换为分钟,再进行比较
let startTimes = startTime.split(':');
let endTimes = endTime.split(':');
let startTimeVal = startTimes[0] * 60 + Number(startTimes[1]);
let endTimeVal = endTimes[0] * 60 + Number(endTimes[1]);
return startTimeVal >= endTimeVal;
}
下面来验证一下 10:15-16:38 这个时间区间
console.log(JSON.stringify(judge('10:15', '16:38')))
输出的结果如下:
[["10:00","11:00"],["11:00","12:00"],["12:00","13:00"],["13:00","14:00"],["14:00","15:00"],["15:00","16:00"],["16:00","17:00"]]
2、包含临界点时间区间的判定
如果给定的时间区间包含了临界时间点,比如 10:00-17:00,那么结果又是如何呢?
console.log(JSON.stringify(judge('10:00', '17:00')))
此时输出的结果如下:
[["10:00","11:00"],["11:00","12:00"],["12:00","13:00"],["13:00","14:00"],["14:00","15:00"],["15:00","16:00"],["16:00","17:00"]]
在实际的应用中,对于临界点时间可能有不同的规则,具体有以下三种场景:
(1)同时算两个时间区间内,比如 16:00 ,既算做位于 ["15:00","16:00"],也算做位于 ["16:00","17:00"] 区间;
(2)临界时间作为结束时间,比如 16:00 ,那么就只算做位于 ["15:00","16:00"] 区间;
(3)临界时间作为起始时间,比如 16:00 ,那么就只算做位于 ["16:00","17:00"] 区间;
如果想同时满足上面的三个场景,那么就需要对判定方法进行改造,通过传入相应的参数进行控制,改造后的代码如下:
function judge(startTime, endTime, leftEquals, rightEquals) {
// 生成24小时时间区间,跨度为1小时
let timeArrays = new Array(24).fill(['', '']).map((item, index) => [(index < 10 ? '0' + index : index) + ':00', ((index + 1) < 10 ? '0' + (index + 1) : (index + 1)) + ':00']);
return timeArrays.filter(item => !((compare(item[0], startTime, leftEquals) && compare(item[0], endTime, rightEquals)) || (compare(startTime, item[1], leftEquals) && compare(endTime, item[1], rightEquals))));
}
function compare(startTime, endTime, equals) {
// 将时间转换为分钟,再进行比较
let startTimes = startTime.split(':');
let endTimes = endTime.split(':');
let startTimeVal = startTimes[0] * 60 + Number(startTimes[1]);
let endTimeVal = endTimes[0] * 60 + Number(endTimes[1]);
return equals ? startTimeVal >= endTimeVal : startTimeVal > endTimeVal;
}
下面分别测试一下上述的三个场景:
场景一:两边都包含,由于是取反的判定方式,所以两个参数都需要传 false
console.log(JSON.stringify(judge('10:00', '12:00', false, false)))
输出结果如下:
[["09:00","10:00"],["10:00","11:00"],["11:00","12:00"],["12:00","13:00"]]
场景二:临界点作为结束时间
console.log(JSON.stringify(judge('10:00', '12:00', false, true)))
输出结果如下:
[["09:00","10:00"],["10:00","11:00"],["11:00","12:00"]]
场景三:临界点作为起始时间
console.log(JSON.stringify(judge('10:00', '12:00', true, false)))
输出结果如下:
[["10:00","11:00"],["11:00","12:00"],["12:00","13:00"]]
3、时间区间跨越0点的判定
在上面讨论的两种情况中,都没有考虑到给定的时间区间跨越0点的问题,即结束时间小于起始时间的情况,比如 10:15-01:23,那么对于这种情况,又需要怎么处理呢?
如果时间区间跨越了0点,那么就相当于存在两个时间区间,即 10:15-24:00 和 00:00-01:23 ,此时就是对两个时间区间进行判定,改造后的代码如下:
function judge(startTime, endTime, leftEquals, rightEquals) {
// 分割时间区间,判定结束时间是否小于起始时间
let targetTimes = compare(startTime, endTime, false) ? [[startTime, '24:00'], ['00:00', endTime]] : [[startTime, endTime]];
// 生成24小时时间区间,跨度为1小时
let timeArrays = new Array(24).fill(['', '']).map((item, index) => [(index < 10 ? '0' + index : index) + ':00', ((index + 1) < 10 ? '0' + (index + 1) : (index + 1)) + ':00']);
return timeArrays.filter(item => targetTimes.some(target => !((compare(item[0], target[0], leftEquals) && compare(item[0], target[1], rightEquals))
|| (compare(target[0], item[1], leftEquals) && compare(target[1], item[1], rightEquals)))));
}
function compare(startTime, endTime, equals) {
// 将时间转换为分钟,再进行比较
let startTimes = startTime.split(':');
let endTimes = endTime.split(':');
let startTimeVal = startTimes[0] * 60 + Number(startTimes[1]);
let endTimeVal = endTimes[0] * 60 + Number(endTimes[1]);
return equals ? startTimeVal >= endTimeVal : startTimeVal > endTimeVal;
}
下面验证一下 10:15-01:23 这个时间区间
console.log(JSON.stringify(judge('10:15', '01:23', false, true)))
输出结果如下
[["00:00","01:00"],["01:00","02:00"],["10:00","11:00"],["11:00","12:00"],["12:00","13:00"],["13:00","14:00"],["14:00","15:00"],["15:00","16:00"],["16:00","17:00"],["17:00","18:00"],["18:00","19:00"],["19:00","20:00"],["20:00","21:00"],["21:00","22:00"],["22:00","23:00"],["23:00","24:00"]]
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK