function toDateRanges(items) { return items .filter(calEvent => { return ( calEvent.start && calEvent.start.dateTime && calEvent.end && calEvent.end.dateTime ); }) .map(calEvent => { return { startDate: new Date(calEvent.start.dateTime), endDate: new Date(calEvent.end.dateTime) }; }) .sort((a, b) => { if (a.startDate.valueOf() < b.startDate.valueOf()) { return -1; } if (a.startDate.valueOf() > b.startDate.valueOf()) { return 1; } return 0; }); } function findGaps(ranges) { let holes = []; for (let i = 1; i < ranges.length; i++) { const beginningOfHole = ranges[i - 1].endDate; const endOfHole = ranges[i].startDate; if (beginningOfHole.valueOf() < endOfHole.valueOf()) { holes.push({ from: beginningOfHole, until: endOfHole }); } } return holes; }