mirror of
https://github.com/multipleof4/lynchmark.git
synced 2026-04-27 19:52:14 +00:00
52 lines
1.6 KiB
JavaScript
52 lines
1.6 KiB
JavaScript
async function findAvailableSlots(cal1, cal2, { durationMinutes, searchRange, workHours }) {
|
|
const { parseISO, addMinutes } = await import('https://cdn.skypack.dev/date-fns');
|
|
const ms = s => parseISO(s).getTime();
|
|
const iso = t => new Date(t).toISOString();
|
|
const parseHM = t => {
|
|
const [h, m] = t.split(':').map(Number);
|
|
return (h * 60 + m) * 60000;
|
|
};
|
|
|
|
const rs = ms(searchRange.start);
|
|
const re = ms(searchRange.end);
|
|
const durMs = durationMinutes * 60000;
|
|
const whS = parseHM(workHours.start);
|
|
const whE = parseHM(workHours.end);
|
|
const DAY = 86400000;
|
|
|
|
const merged = [...cal1, ...cal2]
|
|
.map(b => [ms(b.start), ms(b.end)])
|
|
.filter(([s, e]) => e > rs && s < re)
|
|
.map(([s, e]) => [Math.max(s, rs), Math.min(e, re)])
|
|
.sort((a, b) => a[0] - b[0])
|
|
.reduce((acc, [s, e]) => {
|
|
const last = acc.at(-1);
|
|
if (last && s <= last[1]) last[1] = Math.max(last[1], e);
|
|
else acc.push([s, e]);
|
|
return acc;
|
|
}, []);
|
|
|
|
const free = [];
|
|
let cur = rs;
|
|
for (const [s, e] of merged) {
|
|
if (s > cur) free.push([cur, s]);
|
|
cur = Math.max(cur, e);
|
|
}
|
|
if (cur < re) free.push([cur, re]);
|
|
|
|
const slots = [];
|
|
for (const [fs, fe] of free) {
|
|
for (let day = Math.floor(fs / DAY) * DAY; day < fe; day += DAY) {
|
|
const s = Math.max(fs, day + whS);
|
|
const e = Math.min(fe, day + whE);
|
|
for (let t = s; t + durMs <= e; t = addMinutes(new Date(t), durationMinutes).getTime()) {
|
|
slots.push({ start: iso(t), end: iso(t + durMs) });
|
|
}
|
|
}
|
|
}
|
|
|
|
return slots;
|
|
}
|
|
export default findAvailableSlots;
|
|
// Generation time: 28.829s
|
|
// Result: PASS
|