javascript - 如何找到没有日期部分的时间间隔之间的重叠
问题描述
我必须找出 2 个时间范围之间的重叠,它不包括比较日期部分,但仅包括时间,例如 range_1 是 9AM-6PM,range_2 是 5PM-8AM。实际时间采用 24 小时格式。我已经编写了一个解决方案,可以找到重叠,但是当任何时间处于跨日/午夜之后的时间(例如 10PM-2AM)时它都不起作用
这两个时间都是同一天,但是当必须在午夜之后的任何时间进行比较时,我当前的解决方案无法正常工作。例如,它在 range_1: 9AM-6PM 和 range_2: 5PM-8PM 的情况下给出正确的输出,给出正确的输出 5PM-6PM 重叠,但在 range_1: 10PM-2AM 和 range_2: 1AM-3AM 同一天的情况下找不到重叠。以下是我的codepen的链接:
https://codepen.io/anon/pen/NZOqJm?editors=0010
function overlap(t1,t2)
{
var timeFormat = "hh:mm";
let t1from = moment(t1.timeFrom,timeFormat);
let t1to = moment(t1.timeTo,timeFormat);
let t2from = moment(t2.timeFrom,timeFormat);
let t2to = moment(t2.timeTo,timeFormat);
let overlapFrom = null;
let overlapTo = null;
if (t2from.isBetween(t1from, t1to) && t2to.isBetween(t1from, t1to)) {
//complete overlap
overlapFrom = t2from;
overlapTo = t2to;
}
else if (t1from.isBetween(t2from, t2to) && t1to.isBetween(t2from, t2to))
{
overlapFrom = t1from;
overlapTo = t1to;
}
else if (t2from.isBetween(t1from, t1to)) {
overlapFrom = t2from;
overlapTo = t1to;
}
else if (t2to.isBetween(t1from, t1to)) {
overlapFrom = t1from;
overlapTo = t2to;
}
let doesOverlap = overlapFrom !== null && overlapTo !== null;
let response = {
doesOverlap: doesOverlap,
overlapingMinutes: doesOverlap ? Math.abs(moment.duration(overlapFrom.diff(overlapTo)).asMinutes()): 0,
overlapFrom,
overlapTo
}
return response;
}
/*let t1 = {
timeFrom:'22:00',
timeTo:'02:00'
}
let t2 = {
timeFrom:'01:00',
timeTo:'03:00'
}*/
let t1 = {
timeFrom:'09:00',
timeTo:'18:00'
}
let t2 = {
timeFrom:'17:00',
timeTo:'20:00'
}
console.log(overlap(t1,t2));
range_1:晚上 10 点至凌晨 2 点
range_2:凌晨 1 点至凌晨 3 点
正确的输出应该是:1 AM 到 2 AM
由于两个时间重叠,所有时间都在一天之内,不包括任何日期。将其视为每天有 2 个学生在这些时间学习,如果这些时间重叠,那么两者的时间是什么时候
解决方案
有许多极端情况需要整理,比如“10:00, 11:00”和“11:00, 12:00”是否重叠?“10:00, 10:00”是零分钟还是 24 小时?
无论如何,我这样做的方法是将时间转换为午夜过后的分钟数并进行比较。这段代码的作用就是这样。比较是“一个持续时间的开始时间'在'另一个的开始/结束时间之间”,如果不是,则交换时间并再次检查。
function overlap(t0, t1) {
// convert time to minutes past midnight
var minutes = (d) => {return Object.values(d).map(d => {
d=d.split(':').map(d=>parseInt(d));
return d[0]*60+d[1];
})};
// If the end time is before the start then add 24 hours to the end
// time to wrap it into next day. start==end gets 24 hrs added.
var nextday = (d) => {if(d[0]>=d[1])d[1]+=24*60;return d}
t0 = nextday(minutes(t0));
t1 = nextday(minutes(t1));
var olap = (t0, t1) => {
// beginning of t0 between begin/end of t1
// or
// end of t0 between begin/end of t1
return (t0[0]>=t1[0] && t0[0]<=t1[1])
|| (t1[0]>=t0[0] && t1[0]<=t0[1]);
}
return olap(t0, t1) || olap(t1, t0)
}
推荐阅读
- reactjs - 无法从 Firestore 集合中获取数据
- ruby-on-rails - Rails 的多个数据库不适用于远程数据库
- swift - SwiftUI x Firebase - 在执行代码之前无法等待 Firebase 结果
- reactjs - 无效的钩子调用 - React JS
- javascript - 使用 javascript 或 jquery 将 Html 非表单数据转换为 JSON
- python - 无法使用 python 抓取网站
- python - 使用新变量值更新另一个变量
- bootstrap-5 - data-bs-target="#navbarTogglerDemo01" 为什么这在 Bootstrap-5 上不起作用?
- html - 为什么 CSS 链接行为怪异?
- html - 使画布适合容器