如何找到没有日期部分的时间间隔之间的重叠

时间:2019-07-07 07:48:08

标签: javascript node.js momentjs

我必须找出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

由于两个时间重叠,因此所有时间都在一天之内,并且不包括任何日期。假设这是两名学生每天在这些时间学习,那么如果两者重叠,那么两者都在什么时间

2 个答案:

答案 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)
}