javascript 38 lines · 8 steps

Merging overlapping date ranges

Sort intervals by start date, then sweep once to fold overlapping or adjacent ranges into a compact list.

Explained by highlit
1function mergeDateRanges(ranges) {
2 const parsed = ranges
3 .map(({ start, end }) => ({
4 start: new Date(start),
5 end: new Date(end),
6 }))
7 .filter(({ start, end }) => start <= end)
8 .sort((a, b) => a.start - b.start);
9 
10 const merged = [];
11 
12 for (const range of parsed) {
13 const last = merged[merged.length - 1];
14 
15 if (last && range.start <= addDay(last.end)) {
16 if (range.end > last.end) {
17 last.end = range.end;
18 }
19 } else {
20 merged.push({ ...range });
21 }
22 }
23 
24 return merged.map(({ start, end }) => ({
25 start: toISODate(start),
26 end: toISODate(end),
27 }));
28}
29 
30function addDay(date) {
31 const next = new Date(date);
32 next.setDate(next.getDate() + 1);
33 return next;
34}
35 
36function toISODate(date) {
37 return date.toISOString().slice(0, 10);
38}
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1Sorting intervals by start turns merging into a single left-to-right pass.
  2. 2You only ever need to compare each range against the most recent merged one.
  3. 3Normalizing input early (parsing, filtering) keeps the core algorithm clean and correct.

Related explainers

Share this explainer

Here's the card — post it anywhere.

Merging overlapping date ranges — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code