JavaScript检查时间范围是否重叠

qum*_*uma 4 javascript

我有一个包含2个对象的数组(myObject1和myObject2一样)。现在,当我添加第三个对象时,我将检查时间范围是否重叠。实际上,我不知道如何以一种高效的方式做到这一点。

var myObjectArray = [];

var myObject1 = {};
myObject1.startTime = '08:00';
myObject1.endTime = '12:30';
...

var myObject2 = {};
myObject2.startTime = '11:20';
myObject2.endTime = '18:30';
...

myObjectArray.push(myObject1);
myObjectArray.push(myObject2);
Run Code Online (Sandbox Code Playgroud)

Kon*_*zyb 13

假设我们有一些间隔

const INTERVALS = [
  ['14:00', '15:00'],
  ['08:00', '12:30'],
  ['12:35', '12:36'],
  ['13:35', '13:50'],
];
Run Code Online (Sandbox Code Playgroud)

如果我们想向此列表添加新的间隔,我们应该检查新的间隔是否与其中一些间隔不重叠。

您可以循环槽间隔并检查新间隔是否与其他间隔重叠。请注意,在比较间隔时,如果您确定它是同一天,则不需要 Date 对象,因为您可以将时间转换为数字:

function convertTimeToNumber(time) {
  const hours = Number(time.split(':')[0]);
  const minutes = Number(time.split(':')[1]) / 60;
  return hours + minutes;
}
Run Code Online (Sandbox Code Playgroud)

有两种情况间隔不重叠:

  1. 在 (a < c && a < d) && (b < c && b <d) 之前:
a          b
|----------|
             c          d
             |----------| 
Run Code Online (Sandbox Code Playgroud)
  1. 在 (a > c && a > d) && (b > c && b > d) 之后:
             a          b
             |----------|
c          d
|----------| 
Run Code Online (Sandbox Code Playgroud)

因为 总是c < d,就足以说不重叠间隔的条件是(a < c && b < c) || (a > d && b > d)并且因为 总是a < b,就足以说这个条件相当于:

b < c || a > d
Run Code Online (Sandbox Code Playgroud)

否定这个条件应该给我们一个重叠间隔的条件。根据德摩根定律,它是:

b >= c && a <= d
Run Code Online (Sandbox Code Playgroud)

请注意,在这两种情况下,间隔不能相互“接触”,这意味着 5:00-8:00 和 8:00-9:00 将重叠。如果你想允许的话,条件应该是:

b > c && a < d
Run Code Online (Sandbox Code Playgroud)

至少有 5 种间隔重叠的情况需要考虑:

a          b
|----------|
      c          d
      |----------| 
Run Code Online (Sandbox Code Playgroud)
      a          b
      |----------|
c          d
|----------| 
Run Code Online (Sandbox Code Playgroud)
      a          b
      |----------|
c                    d
|--------------------|
Run Code Online (Sandbox Code Playgroud)
a                    b
|--------------------|
      c          d
      |----------|
Run Code Online (Sandbox Code Playgroud)
a          b
|----------|
c          d
|----------|
Run Code Online (Sandbox Code Playgroud)

具有额外添加和排序间隔功能的完整代码如下:

a          b
|----------|
             c          d
             |----------| 
Run Code Online (Sandbox Code Playgroud)

  • 这是因为它应该是同一天。间隔 23-01 是另一天。 (2认同)

Dan*_*din 6

将moment-jsmoment-range一起使用(损坏的参考)

测试示例:

const range1 = moment.range(a, c);
const range2 = moment.range(b, d);
range1.overlaps(range2); // true
Run Code Online (Sandbox Code Playgroud)

请参阅https://github.com/rotaready/moment-range#overlaps中的更多示例

请注意,要使上述代码正常工作,您可能首先需要执行以下操作:

<script src="moment.js"></script>
<script src="moment-range.js"></script>

window['moment-range'].extendMoment(moment);
Run Code Online (Sandbox Code Playgroud)

HTML代码

<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.12.0/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-range/2.2.0/moment-range.min.js"></script>
Run Code Online (Sandbox Code Playgroud)

JavaScript 代码

var range  = moment.range(new Date(year, month, day, hours, minutes), new Date(year, month, day, hours, minutes));
var range2 = moment.range(new Date(year, month, day, hours, minutes), new Date(year, month, day, hours, minutes));
range.overlaps(range2); // true or flase
Run Code Online (Sandbox Code Playgroud)

非常简洁的解决方案,并momentjs附带大量的日期和时间实用程序。


Raj*_*esh 5

您可以尝试如下操作:

var timeList = [];

function addTime() {
  var startTime = document.getElementById("startTime").value;
  var endTime = document.getElementById("endTime").value;

  if (validate(startTime, endTime)){
    timeList.push({
      startTime: startTime,
      endTime: endTime
    });
    print(timeList);
    document.getElementById("error").innerHTML = "";
    }
  else
    document.getElementById("error").innerHTML = "Please select valid time";
}

function validate(sTime, eTime) {
  if (+getDate(sTime) < +getDate(eTime)) {
    var len = timeList.length;
    return len>0?(+getDate(timeList[len - 1].endTime) < +getDate(sTime) ):true;
  } else {
    return false;
  }
}

function getDate(time) {
  var today = new Date();
  var _t = time.split(":");
  today.setHours(_t[0], _t[1], 0, 0);
  return today;
}
function print(data){
  document.getElementById("content").innerHTML = "<pre>" + JSON.stringify(data, 0, 4) + "</pre>";
}
Run Code Online (Sandbox Code Playgroud)
<input type="text" id="startTime" />
<input type="text" id="endTime" />
<button onclick="addTime()">Add Time</button>
<p id="error"></p>

<div id="content"></div>
Run Code Online (Sandbox Code Playgroud)


小智 0

要确定时间范围是否与其他时间范围重叠,您可以同时使用moment.jsmoment-range库。

首先安装moment-jsmoment-range 假设您有一个包含示例对象的 INTERVALS 数组:

const INTERVALS = [
    { START: 0, END: 10 },
    { START: 12, END: 30 },
    ...
]
Run Code Online (Sandbox Code Playgroud)

您可以使用下面的函数:

const validateIntervalOverlaps = () => {
if (INTERVAL_START && INTERVAL__END) {
  const timeInterval = moment.range(moment(INTERVAL_START), moment(INTERVAL_ENDS))

  const overlappingInterval = INTERVALS.find(intervalItem => {
    const interval = moment.range(moment(intervalItem.START), moment(intervalItem.END))
    return timeInterval.overlaps(interval)
  })

  return overlappingInterval
}
Run Code Online (Sandbox Code Playgroud)

}

接下来,您可以使用重叠间隔做您需要做的事情:) Fe 确定它是否存在或以任何其他方式使用它。祝你好运!