Check if Two Date Ranges Overlap in JavaScript
To test whether two half-open date ranges overlap, check aStart < bEnd && bStart < aEnd — true only when they share at least one day. Part of Working with Date Ranges and Intervals.
Why this scenario is tricky
The overlap test people reach for first — checking whether either range's start falls inside the other — misses the case where one range fully contains the other, and it double-checks the case where they merely touch. The correct condition is famously terse but easy to get backwards: two half-open ranges [aStart, aEnd) and [bStart, bEnd) overlap exactly when aStart < bEnd and bStart < aEnd. The strict < (not <=) is what makes touching ranges — where one ends exactly as the other begins — count as not overlapping, which is almost always what a scheduler wants.
Minimal working solution
Compare the endpoints with Temporal.PlainDate.compare. Touching ranges do not overlap under the half-open convention.
import { Temporal } from '@js-temporal/polyfill';
const lt = (x: Temporal.PlainDate, y: Temporal.PlainDate) => Temporal.PlainDate.compare(x, y) < 0;
function overlaps(aS, aE, bS, bE: Temporal.PlainDate) {
// Overlap iff a starts before b ends AND b starts before a ends.
return lt(aS, bE) && lt(bS, aE);
}
Full production version
A production helper validates each range, returns whether they overlap, and optionally the overlapping sub-range (useful for merging calendars).
import { Temporal } from '@js-temporal/polyfill';
type R = { start: Temporal.PlainDate; end: Temporal.PlainDate };
const cmp = Temporal.PlainDate.compare;
function intersection(a: R, b: R): R | null {
if (cmp(a.start, a.end) > 0 || cmp(b.start, b.end) > 0) throw new RangeError('inverted range');
const start = cmp(a.start, b.start) >= 0 ? a.start : b.start; // later start
const end = cmp(a.end, b.end) <= 0 ? a.end : b.end; // earlier end
return cmp(start, end) < 0 ? { start, end } : null; // empty => no overlap
}
Verification
Common pitfalls
Frequently Asked Questions
What is the simplest way to check if two date ranges overlap?
Two half-open ranges overlap when the first starts before the second ends and the second starts before the first ends: aStart < bEnd && bStart < aEnd. Use strict less-than so ranges that merely touch at a boundary are treated as non-overlapping.
Do ranges that touch at an endpoint overlap?
Under the half-open [start, end) convention they do not. Because the end is exclusive, a range ending on the same day another begins shares no day, so the strict comparison returns false. That is what you want for back-to-back bookings.