我必须找出2个时间范围之间的重叠,并且比较中不包括日期部分,而只有时间,例如range_1是9 AM-6PM,range_2是5 PM-8AM。实际时间为24小时制。我已经编写了一个解决方案,该解决方案可以找到重叠部分,但是当任何时间在跨日/午夜后的任何时间(例如10 PM-2AM)时都无效
两个时间都是同一天,但是当必须在午夜之后的任何时间进行比较时,我当前的解决方案无法正常工作。例如,在范围_1:9 AM-6PM和范围_2:5 PM-8PM的情况下,它给出正确的输出,在正确的情况下给出输出5 PM-6PM的重叠,但是在当天范围_1:10 PM-2AM和范围_2:1 AM-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));
范围_1:10 PM-2AM
range_2:1 AM-3AM
正确的输出应为:1 AM至2 AM
由于两个时间重叠,因此所有时间都在一天之内,并且不包括任何日期。假设这是两名学生每天在这些时间学习,那么如果两者重叠,那么两者都在什么时间
答案 0 :(得分:0)
然后我将只花几个小时/分钟:
const smaller = (a, b) => a.hours < b.hours || (a.hours === b.hours && a.mins < b.mins);
const equals = (a, b) => a.hours === b.hours && a.mins === b.mins;
function overlap(a, b) {
if(smaller(a.to, a.from)) {
return [
...overlap({ from: { hours: 0, mins: 0}, to: a.to }, b),
...overlap({ from: a.from, to: { hours: 24, mins: 0 }}, b),
];
}
if(smaller(b.to, b.from)) {
return [
...overlap(a, { from: { hours: 0, mins: 0}, to: a.to }),
...overlap(a, { from: a.from, to: { hours: 24, mins: 0 }}),
];
}
const result = {
from: smaller(b.from, a.from) ? a.from : b.from,
to: smaller(a.to, b.to) ? a.to : b.to,
};
return equals(result.from, result.to) ? [] : [result];
}
console.log(...[
[
{ from: { hours: 6, mins: 10 }, to: { hours: 8, mins: 10 }},
{ from: { hours: 6, mins: 10 }, to: { hours: 8, mins: 10 }}
], [
{ from: { hours: 7, mins: 10 }, to: { hours: 10, mins: 10 }},
{ from: { hours: 6, mins: 10 }, to: { hours: 8, mins: 10 }}
], [
{ from: { hours: 23, mins: 10 }, to: { hours: 8, mins: 10 }},
{ from: { hours: 6, mins: 10 }, to: { hours: 8, mins: 10 }}
]
].map(([a, b]) => `${JSON.stringify(a)}\n overlaps with ${JSON.stringify(b)}\n in ${JSON.stringify(overlap(a, b))}\n\n`));
答案 1 :(得分:0)
有很多情况需要解决,例如 “ 10:00,11:00”和“ 11:00,12:00”重叠吗?并且“ 00: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)
}