0

My function for checking if two range of dates are overlapping doesn't work when I use YYYY-MM-DDTHH:MM:SSZ format

The second example of the date rent2 and book2 have the same date, but the time is different, so it should not detect the overlapping

const rent = {
  start: new Date("2019-03-10"),
  end:   new Date("2019-03-14")
}

const book = {
  start: new Date("2019-03-15"),
  end:   new Date("2019-03-18"),
}

const rent2 = {
  start: new Date("2019-03-10T01:00:00Z"),
  end:   new Date("2019-03-14T10:00:00Z")
}

const book2 = {
  start: new Date("2019-03-10T12:00:00Z"),
  end:   new Date("2019-03-14T15:00:00Z"),
}

function isOverlapping(startOne, endOne, startTwo, endTwo) {

  startOne = startOne.getTime();
  startTwo = startTwo.getTime();
  endOne = endOne.getTime();
  endTwo = endTwo.getTime();

  return !(endOne <= startTwo || startOne >= endTwo);

}

console.log("First: ", isOverlapping(rent.start, rent.end, book.start, book.end));
console.log("Second: ", isOverlapping(rent2.start, rent2.end, book2.start, book2.end));
Denis Lapadatovic
  • 305
  • 1
  • 9
  • 16
  • what do you mean with "Should not detect the difference"? – Brainmaniac Sep 01 '19 at 16:43
  • Even if the date is the same (`2019-03-10`) user will be able to rent the book from `01:00 - 10:00` because other user rented it from `12:00 - 15:00` - This means there is no overlap between this two users even if the date is the same. – Denis Lapadatovic Sep 01 '19 at 16:57
  • You don't need to call *getTime*, you can leave the values as Date objects and do `(startOne >= startTwo && startOne < endTwo) || (endOne > startTwo && endOne <= endTwo)`, assuming that where one range ends on the start of another range does not count as "overlap". – RobG Sep 02 '19 at 01:09

2 Answers2

0

Your function works perfectly fine - rent and book do not overlap, while rent2 and book2 do overlap.

If you need to compute the actual amount of overlapping between 2 date ranges, you can use the following function:

function getOverlapping(startOne, endOne, startTwo, endTwo)
{
  return Math.max(0, 
    endOne.getTime() 
    - startOne.getTime() 
    - Math.max(0, 
      endOne.getTime() 
      - endTwo.getTime()) 
    - Math.max(0, 
      startTwo.getTime() 
      - startOne.getTime()));
}

If the result is non-zero - then there is an overlapping.

The formula makes an assumption that one of the ranges is completely contained within the other range - so it computes the length of the containing range and then tries to subtract the 2 intervals (on the left and on the right) surrounding the contained range to find the amount of overlapping. If either the left or the right interval turns out to be negative, we cap them to 0.

IVO GELOV
  • 13,496
  • 1
  • 17
  • 26
  • Code-only answers aren't very helpful. A good answer should explain why the OP has their issue and how your code fixes it. Your method is a rather convoluted way of going about the comparison. It's much clearer to determine if the start or end of one range is within the bounds of a second range. E.g. for ranges a–b and c–d, `(a >= c && a < d) || (b > c && b <= d)`. The brackets are for clarity. – RobG Sep 02 '19 at 03:04
  • As explained in https://logic-and-trick.com/post/the-overlapping-date-range-test the formula can be simplified even further - `(endOne > startTwo && startOne < endTwo)` It seems cleaner to me. The formula that I used provides a numeric output - so you not only determine whether there is an overlapping but also the amount of overlapping (which might or might not be of any use to the OP). – IVO GELOV Sep 02 '19 at 09:36
0

It has nothing to do with time in it self. But because of your boolean-flip it gets a bitt tricky read.

Case 1

("2019-03-14" <= "2019-03-15" || "2019-03-10" >= "2019-03-18")

_____________true____________________________false____________

As it is a or => true is returned... AND then flipped to false

Case 2

("2019-03-14T10:00:00Z" <= "2019-03-10T12:00:00Z") ______________________false_______________________

||

"2019-03-10T01:00:00Z" >= "2019-03-14T15:00:00Z")

______________________false_______________________

No true so false is returned... AND then flipped to true


I would recommend to have a look at this thread for example: Determine Whether Two Date Ranges Overlap

Brainmaniac
  • 2,203
  • 4
  • 29
  • 53