Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check if times overlap using moment?

I have an array of [start_time, end_time] time ranges like so:

let timeSegments = [];
timeSegments.push(["02:00", "07:00"])
timeSegments.push(["03:00", "04:00"])

These time segments overlap, since 2AM - 7AM includes 3AM - 4AM

Likewise:

let timeSegments = [];
timeSegments.push(["14:00", "18:00"])
timeSegments.push(["15:00", "19:00"])

2PM to 6PM overlaps with 3PM to 7PM.

I'm using the momentjs library, and would like to know a way to determine if my timeSegments array contains any timeSegments that overlap? The timeSegments array can contain at most 10 [start_time, end_time] pairs. Thanks!

I'd just like to know if any segments overlap (true/false), I don't need to know which of the segments overlap etc.

like image 255
Rory Avatar asked Jun 28 '17 10:06

Rory


People also ask

How do you calculate overlap time?

Overlap = min(A2, B2) - max(A1, B1) + 1. In other words, the overlap of two integer intervals is a difference between the minimum value of the two upper boundaries and the maximum value of the two lower boundaries, plus 1.

How do you know if two time ranges overlap?

1) Sort all intervals in increasing order of start time. This step takes O(nLogn) time. 2) In the sorted array, if start time of an interval is less than end of previous interval, then there is an overlap.

How does SQL determine overlapping dates?

You can do this by swapping the ranges if necessary up front. Then, you can detect overlap if the second range start is: less than or equal to the first range end (if ranges are inclusive, containing both the start and end times); or. less than (if ranges are inclusive of start and exclusive of end).

How does Javascript determine overlapping time intervals?

const arr = [ { start: '01:00', end: '04:00' }, { start: '05:00', end: '08:00' }, { start: '07:00', end: '11:00' }, { start: '09:30', end: '18:00' }, ]; Our function should iterate through this array of objects and check all elements of the array against the others.


1 Answers

You can sort timeSegments by start_time (using Array.prototype.sort) and iterate through the sorted list and check if end_time of the current timeSegment is greater than start_time of the next one.

If that happens, there is an overlap.

You can see an example of implementation below:

const checkOverlap = (timeSegments) => {
  if (timeSegments.length === 1) return false;

  timeSegments.sort((timeSegment1, timeSegment2) =>
    timeSegment1[0].localeCompare(timeSegment2[0])
  );

  for (let i = 0; i < timeSegments.length - 1; i++) {
    const currentEndTime = timeSegments[i][1];
    const nextStartTime = timeSegments[i + 1][0];

    if (currentEndTime > nextStartTime) {
      return true;
    }
  }

  return false;
};

const timeSegments1 = [
  ["03:00", "04:00"],
  ["02:00", "07:00"],
  ["12:00", "15:00"]
];

const timeSegments2 = [
  ["05:00", "07:00"],
  ["03:00", "04:00"],
  ["12:00", "15:00"]
];

console.log(checkOverlap(timeSegments1)); // prints true
console.log(checkOverlap(timeSegments2)); // prints false

Note that Array.prototype.sort mutates the array, performing the sort in-place. If you want to preserve the array passed to checkOverlap (which is, in general, a good practice), you can create a copy of timeSegments (using the spread syntax, for example):

const sortedTimeSegments = [...timeSegments].sort(...);
like image 137
Alberto Trindade Tavares Avatar answered Oct 06 '22 10:10

Alberto Trindade Tavares