mirror of
https://github.com/multipleof4/lynchmark.git
synced 2026-01-14 00:27:55 +00:00
50 lines
1.4 KiB
JavaScript
50 lines
1.4 KiB
JavaScript
export const findAvailableSlots = async (calA, calB, { durationMinutes: dur, searchRange: range, workHours: work }) => {
|
|
const { formatISO, addMinutes } = await import('https://esm.sh/date-fns@3.6.0');
|
|
const toMs = (d) => new Date(d).getTime();
|
|
const slotMs = dur * 6e4;
|
|
const limit = toMs(range.end);
|
|
|
|
const parseTime = t => t.split(':').reduce((h, m) => h * 60 + +m, 0);
|
|
const [wStart, wEnd] = [work.start, work.end].map(parseTime);
|
|
|
|
const busy = [...calA, ...calB]
|
|
.map(x => ({ s: toMs(x.start), e: toMs(x.end) }))
|
|
.sort((a, b) => a.s - b.s)
|
|
.reduce((a, c) => {
|
|
const l = a.at(-1);
|
|
(l && c.s <= l.e) ? l.e = Math.max(l.e, c.e) : a.push(c);
|
|
return a;
|
|
}, []);
|
|
|
|
let now = toMs(range.start);
|
|
let bIdx = 0;
|
|
const res = [];
|
|
|
|
while (now + slotMs <= limit) {
|
|
const d = new Date(now);
|
|
const dayBase = Date.UTC(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate());
|
|
const [dayStart, dayEnd] = [dayBase + wStart * 6e4, dayBase + wEnd * 6e4];
|
|
|
|
if (now < dayStart) {
|
|
now = dayStart;
|
|
continue;
|
|
}
|
|
if (now + slotMs > dayEnd) {
|
|
now = dayStart + 864e5;
|
|
continue;
|
|
}
|
|
|
|
while (busy[bIdx] && busy[bIdx].e <= now) bIdx++;
|
|
const b = busy[bIdx];
|
|
|
|
if (b && b.s < now + slotMs) {
|
|
now = b.e;
|
|
} else {
|
|
res.push({ start: formatISO(now), end: formatISO(addMinutes(now, dur)) });
|
|
now += slotMs;
|
|
}
|
|
}
|
|
|
|
return res;
|
|
};
|
|
export default findAvailableSlots; |