mirror of
https://github.com/multipleof4/lynchmark.git
synced 2026-01-14 16:47:55 +00:00
45 lines
1.5 KiB
JavaScript
45 lines
1.5 KiB
JavaScript
const findAvailableSlots = async (cal1, cal2, { durationMinutes: dur, searchRange: range, workHours: work }) => {
|
|
const { parseISO } = await import('https://esm.sh/date-fns@2.30.0')
|
|
const toMs = d => parseISO(d).getTime()
|
|
|
|
const busy = [...cal1, ...cal2]
|
|
.map(c => ({ s: toMs(c.start), e: toMs(c.end) }))
|
|
.sort((a, b) => a.s - b.s)
|
|
.reduce((acc, c) => {
|
|
const last = acc[acc.length - 1]
|
|
if (last && c.s < last.e) last.e = Math.max(last.e, c.e)
|
|
else acc.push(c)
|
|
return acc
|
|
}, [])
|
|
|
|
const start = toMs(range.start), end = toMs(range.end), ms = dur * 60000
|
|
const [sh, sm] = work.start.split(':'), [eh, em] = work.end.split(':')
|
|
const slots = []
|
|
|
|
for (let d = new Date(start); d < end; d.setUTCDate(d.getUTCDate() + 1)) {
|
|
d.setUTCHours(0, 0, 0, 0)
|
|
const y = d.getUTCFullYear(), m = d.getUTCMonth(), day = d.getUTCDate()
|
|
const wStart = Math.max(Date.UTC(y, m, day, sh, sm), start)
|
|
const wEnd = Math.min(Date.UTC(y, m, day, eh, em), end)
|
|
|
|
if (wStart >= wEnd) continue
|
|
|
|
let ptr = wStart
|
|
for (const b of busy) {
|
|
if (b.e <= ptr) continue
|
|
if (b.s >= wEnd) break
|
|
while (ptr + ms <= b.s) {
|
|
slots.push({ start: new Date(ptr).toISOString(), end: new Date(ptr + ms).toISOString() })
|
|
ptr += ms
|
|
}
|
|
ptr = Math.max(ptr, b.e)
|
|
}
|
|
while (ptr + ms <= wEnd) {
|
|
slots.push({ start: new Date(ptr).toISOString(), end: new Date(ptr + ms).toISOString() })
|
|
ptr += ms
|
|
}
|
|
}
|
|
|
|
return slots
|
|
}
|
|
export default findAvailableSlots; |