Given two date ranges, what is the simplest or most efficient way to determine whether the two date ranges overlap?

As an example, suppose we have ranges denoted by DateTime variables `StartDate1`

to `EndDate1`

*and* `StartDate2`

to `EndDate2`

.

Skip to content
# Determine Whether Two Date Ranges Overlap

###### Related Question

datetimelanguage-agnosticmath

Given two date ranges, what is the simplest or most efficient way to determine whether the two date ranges overlap?

As an example, suppose we have ranges denoted by DateTime variables `StartDate1`

to `EndDate1`

*and* `StartDate2`

to `EndDate2`

.

- Java – Fastest way to determine if an integer’s square root is an integer
- Javascript – Compare two dates with JavaScript
- Javascript – Add days to JavaScript Date
- Python – How to get the day of week given a date
- How to determine whether the calculation of pi is accurate
- How to pair socks from a pile efficiently
- Javascript – Moment js date time comparison

## Best Solution

(StartA <= EndB) and (EndA >= StartB)Proof:Let ConditionA Mean that DateRange A Completely After DateRange B

(True if

`StartA > EndB`

)Let ConditionB Mean that DateRange A is Completely Before DateRange B

(True if

`EndA < StartB`

)Then Overlap exists if Neither A Nor B is true -

(If one range is neither completely after the other,

nor completely before the other, then they must overlap.)

Now one of De Morgan's laws says that:

`Not (A Or B)`

<=>`Not A And Not B`

Which translates to:

`(StartA <= EndB) and (EndA >= StartB)`

NOTE: This includes conditions where the edges overlap exactly. If you wish to exclude that,

change the

`>=`

operators to`>`

, and`<=`

to`<`

NOTE2. Thanks to @Baodad, see this blog, the actual overlap is least of:

{

`endA-startA`

,`endA - startB`

,`endB-startA`

,`endB - startB`

}`(StartA <= EndB) and (EndA >= StartB)`

`(StartA <= EndB) and (StartB <= EndA)`

NOTE3. Thanks to @tomosius, a shorter version reads:

`DateRangesOverlap = max(start1, start2) < min(end1, end2)`

This is actually a syntactical shortcut for what is a longer implementation, which includes extra checks to verify that the start dates are on or before the endDates. Deriving this from above:

If start and end dates can be out of order, i.e., if it is possible that

`startA > endA`

or`startB > endB`

, then you also have to check that they are in order, so that means you have to add two additional validity rules:`(StartA <= EndB) and (StartB <= EndA) and (StartA <= EndA) and (StartB <= EndB)`

or:`(StartA <= EndB) and (StartA <= EndA) and (StartB <= EndA) and (StartB <= EndB)`

or,`(StartA <= Min(EndA, EndB) and (StartB <= Min(EndA, EndB))`

or:`(Max(StartA, StartB) <= Min(EndA, EndB)`

But to implement

`Min()`

and`Max()`

, you have to code, (using C ternary for terseness),:`(StartA > StartB? Start A: StartB) <= (EndA < EndB? EndA: EndB)`