mirror of
https://github.com/multipleof4/lynchmark.git
synced 2026-06-28 04:12:13 +00:00
42 lines
1.4 KiB
JavaScript
42 lines
1.4 KiB
JavaScript
const findAvailableSlots = async (calendarA, calendarB, { durationMinutes, searchRange, workHours }) => {
|
|
const { DateTime, Interval } = await import('https://cdn.jsdelivr.net/npm/luxon@3/+esm');
|
|
|
|
const utc = s => DateTime.fromISO(s, { zone: 'utc' });
|
|
const parseHM = s => s.split(':').map(Number);
|
|
|
|
const range = Interval.fromDateTimes(utc(searchRange.start), utc(searchRange.end));
|
|
const busy = Interval.merge(
|
|
[...calendarA, ...calendarB].map(({ start, end }) => Interval.fromDateTimes(utc(start), utc(end)))
|
|
);
|
|
const free = range.difference(...busy);
|
|
|
|
const [wsH, wsM] = parseHM(workHours.start);
|
|
const [weH, weM] = parseHM(workHours.end);
|
|
const slots = [];
|
|
|
|
for (const period of free) {
|
|
let day = period.start.startOf('day');
|
|
while (day < period.end) {
|
|
const workWindow = Interval.fromDateTimes(
|
|
day.set({ hour: wsH, minute: wsM }),
|
|
day.set({ hour: weH, minute: weM })
|
|
);
|
|
const window = period.intersection(workWindow);
|
|
if (window) {
|
|
let cursor = window.start;
|
|
let next = cursor.plus({ minutes: durationMinutes });
|
|
while (next <= window.end) {
|
|
slots.push({ start: cursor.toISO(), end: next.toISO() });
|
|
cursor = next;
|
|
next = cursor.plus({ minutes: durationMinutes });
|
|
}
|
|
}
|
|
day = day.plus({ days: 1 });
|
|
}
|
|
}
|
|
|
|
return slots;
|
|
};
|
|
export default findAvailableSlots;
|
|
// Generation time: 20.786s
|
|
// Result: PASS
|