Slot generation, availability checking, and conflict detection

Import

import { ... } from 'ts-time-utils/scheduling';

Examples

Generate Time Slots

Create bookable time slots for a day or range

import { generateSlots, generateSlotsForRange } from 'ts-time-utils/scheduling';

// Generate 30-minute slots for a day
const slots = generateSlots(new Date('2025-01-15'), { slotDuration: 30 });
console.log(`Generated ${slots.length} slots`);

slots.slice(0, 5).forEach(slot => {
  console.log(`${slot.start.toLocaleTimeString()} - ${slot.end.toLocaleTimeString()}: ${slot.available ? 'Available' : 'Booked'}`);
});

// Generate slots for a date range
const range = {
  start: new Date('2025-01-15'),
  end: new Date('2025-01-17')
};
const rangeSlots = generateSlotsForRange(range, { slotDuration: 60 });
console.log(`Generated ${rangeSlots.length} slots across range`);

Availability & Conflicts

Check availability and detect booking conflicts

import { getAvailableSlots, findNextAvailable, isSlotAvailable, findConflicts, hasConflict } from 'ts-time-utils/scheduling';

// Existing bookings
const bookings = [
  { start: new Date('2025-01-15T10:00'), end: new Date('2025-01-15T11:00'), id: 'meeting-1' },
  { start: new Date('2025-01-15T14:00'), end: new Date('2025-01-15T15:30'), id: 'meeting-2' },
];

// Get available slots
const available = getAvailableSlots(new Date('2025-01-15'), bookings, { slotDuration: 30 });
console.log(`${available.length} available slots`);

// Find next 1-hour slot
const nextSlot = findNextAvailable(new Date('2025-01-15T09:00'), bookings, 60);
console.log('Next 1-hour slot:', nextSlot?.start.toLocaleTimeString());

// Check if specific slot is available
const proposed = { start: new Date('2025-01-15T10:30'), end: new Date('2025-01-15T11:30') };
console.log('Is 10:30-11:30 available?', isSlotAvailable(proposed, bookings));

// Find conflicts
const conflicts = findConflicts(bookings, proposed);
console.log('Conflicts:', conflicts.map(c => c.id));

// Quick conflict check
console.log('Has conflict?', hasConflict(bookings, proposed));

Buffer & Merge

Add buffers between bookings and merge adjacent slots

import { addBuffer, removeBuffer, mergeBookings, splitSlot } from 'ts-time-utils/scheduling';

// Add 15-minute buffer around a meeting
const meeting = {
  start: new Date('2025-01-15T10:00'),
  end: new Date('2025-01-15T11:00')
};

const buffered = addBuffer(meeting, 15);
console.log('With buffer:', buffered.start.toLocaleTimeString(), '-', buffered.end.toLocaleTimeString());
// 09:45 - 11:15

const original = removeBuffer(buffered, 15);
console.log('Without buffer:', original.start.toLocaleTimeString(), '-', original.end.toLocaleTimeString());

// Merge adjacent bookings
const bookings = [
  { start: new Date('2025-01-15T09:00'), end: new Date('2025-01-15T10:00') },
  { start: new Date('2025-01-15T10:00'), end: new Date('2025-01-15T11:00') },
  { start: new Date('2025-01-15T14:00'), end: new Date('2025-01-15T15:00') },
];

const merged = mergeBookings(bookings);
console.log(`${bookings.length} bookings merged to ${merged.length}`);

// Split a slot
const slot = { start: new Date('2025-01-15T09:00'), end: new Date('2025-01-15T11:00'), available: true };
const result = splitSlot(slot, new Date('2025-01-15T10:00'));
if (result) {
  const [before, after] = result;
  console.log('Before:', before.start.toLocaleTimeString(), '-', before.end.toLocaleTimeString());
  console.log('After:', after.start.toLocaleTimeString(), '-', after.end.toLocaleTimeString());
}