mirror of
https://github.com/multipleof4/lynchmark.git
synced 2026-01-14 16:47:55 +00:00
55 lines
1.8 KiB
JavaScript
55 lines
1.8 KiB
JavaScript
const findAvailableSlots = async (calendarA, calendarB, { durationMinutes, searchRange, workHours }) => {
|
|
const { addMinutes, formatISO } = await import('https://cdn.jsdelivr.net/npm/date-fns@3.6.0/+esm');
|
|
const T = (d) => new Date(d).getTime();
|
|
const durMs = durationMinutes * 60000;
|
|
const rangeEnd = T(searchRange.end);
|
|
|
|
const busy = [...calendarA, ...calendarB]
|
|
.map(s => ({ s: T(s.start), e: T(s.end) }))
|
|
.sort((a, b) => a.s - b.s)
|
|
.reduce((acc, c) => {
|
|
if (acc.length && c.s < acc[acc.length - 1].e) {
|
|
acc[acc.length - 1].e = Math.max(acc[acc.length - 1].e, c.e);
|
|
} else {
|
|
acc.push(c);
|
|
}
|
|
return acc;
|
|
}, []);
|
|
|
|
const slots = [];
|
|
let currentDay = new Date(searchRange.start);
|
|
currentDay.setUTCHours(0, 0, 0, 0);
|
|
|
|
while (currentDay.getTime() < rangeEnd) {
|
|
const dateStr = currentDay.toISOString().split('T')[0];
|
|
const workStart = T(`${dateStr}T${workHours.start}:00Z`);
|
|
const workEnd = T(`${dateStr}T${workHours.end}:00Z`);
|
|
|
|
const winStart = Math.max(workStart, T(searchRange.start));
|
|
const winEnd = Math.min(workEnd, rangeEnd);
|
|
|
|
if (winStart < winEnd) {
|
|
let cursor = winStart;
|
|
|
|
for (const b of busy) {
|
|
if (b.e <= cursor) continue;
|
|
if (b.s >= winEnd) break;
|
|
|
|
while (cursor + durMs <= b.s) {
|
|
slots.push({ start: formatISO(cursor), end: formatISO(addMinutes(cursor, durationMinutes)) });
|
|
cursor += durMs;
|
|
}
|
|
cursor = Math.max(cursor, b.e);
|
|
}
|
|
|
|
while (cursor + durMs <= winEnd) {
|
|
slots.push({ start: formatISO(cursor), end: formatISO(addMinutes(cursor, durationMinutes)) });
|
|
cursor += durMs;
|
|
}
|
|
}
|
|
currentDay.setUTCDate(currentDay.getUTCDate() + 1);
|
|
}
|
|
|
|
return slots;
|
|
};
|
|
export default findAvailableSlots; |