mirror of
https://github.com/multipleof4/lynchmark.git
synced 2026-01-14 00:27:55 +00:00
52 lines
1.7 KiB
JavaScript
52 lines
1.7 KiB
JavaScript
const findAvailableSlots = async (cal1, cal2, { durationMinutes: dur, searchRange: range, workHours: work }) => {
|
|
const { parseISO } = await import('https://cdn.jsdelivr.net/npm/date-fns@3.6.0/+esm');
|
|
|
|
const toMs = (d) => parseISO(d).getTime();
|
|
const [wsH, wsM] = work.start.split(':').map(Number);
|
|
const [weH, weM] = work.end.split(':').map(Number);
|
|
const rangeStart = toMs(range.start);
|
|
const rangeEnd = toMs(range.end);
|
|
const durMs = dur * 60000;
|
|
|
|
const busy = [...cal1, ...cal2]
|
|
.map(x => ({ s: toMs(x.start), e: toMs(x.end) }))
|
|
.sort((a, b) => a.s - b.s);
|
|
|
|
const merged = [];
|
|
for (const b of busy) {
|
|
const last = merged[merged.length - 1];
|
|
if (last && b.s < last.e) last.e = Math.max(last.e, b.e);
|
|
else merged.push(b);
|
|
}
|
|
|
|
const slots = [];
|
|
let currDate = parseISO(range.start);
|
|
currDate.setUTCHours(0, 0, 0, 0);
|
|
|
|
while (currDate.getTime() < rangeEnd) {
|
|
const wStart = new Date(currDate).setUTCHours(wsH, wsM, 0, 0);
|
|
const wEnd = new Date(currDate).setUTCHours(weH, weM, 0, 0);
|
|
|
|
let t = Math.max(wStart, rangeStart);
|
|
const limit = Math.min(wEnd, rangeEnd);
|
|
|
|
while (t + durMs <= limit) {
|
|
const tEnd = t + durMs;
|
|
const clash = merged.find(b => t < b.e && tEnd > b.s);
|
|
|
|
if (clash) {
|
|
t = clash.e;
|
|
} else {
|
|
slots.push({
|
|
start: new Date(t).toISOString(),
|
|
end: new Date(tEnd).toISOString()
|
|
});
|
|
t += durMs;
|
|
}
|
|
}
|
|
currDate.setUTCDate(currDate.getUTCDate() + 1);
|
|
}
|
|
|
|
return slots;
|
|
};
|
|
export default findAvailableSlots; |