ExBooking. Slotting
(ExBooking v0.1.0)
View Source
Candidate slot generation.
Slotting cuts free intervals into bookable starts. Duration controls how
long each slot is; step controls how often starts are offered. The default
grid starts at the free interval boundary, while align: :clock snaps to
UTC clock boundaries such as :00, :15, :30, and :45.
Example
iex> free = ExBooking.Interval.new!(~U[2026-07-13 09:00:00Z], ~U[2026-07-13 10:00:00Z])
...> free |> ExBooking.Slotting.generate_slots(30, 15) |> Enum.map(& &1.start_at)
[~U[2026-07-13 09:00:00Z], ~U[2026-07-13 09:15:00Z], ~U[2026-07-13 09:30:00Z]]
Summary
Functions
Generates slots across many free intervals, deduplicated and sorted.
Generates candidate slots of duration_min minutes on a step_min grid
anchored to the free interval's start by default.
Functions
@spec generate_all([ExBooking.Interval.t()], pos_integer(), pos_integer(), keyword()) :: [ ExBooking.Interval.t() ]
Generates slots across many free intervals, deduplicated and sorted.
Duplicate starts can occur when free intervals from different sources overlap after DST normalization; the first occurrence wins.
Examples
iex> a = ExBooking.Interval.new!(~U[2026-07-13 09:00:00Z], ~U[2026-07-13 09:30:00Z])
...> b = ExBooking.Interval.new!(~U[2026-07-13 09:00:00Z], ~U[2026-07-13 09:30:00Z])
...> ExBooking.Slotting.generate_all([a, b], 30, 30) |> length()
1
@spec generate_slots(ExBooking.Interval.t(), pos_integer(), pos_integer(), keyword()) :: [ ExBooking.Interval.t() ]
Generates candidate slots of duration_min minutes on a step_min grid
anchored to the free interval's start by default.
Options:
:align—:free_start(default) or:clock
Every returned slot fits entirely inside free and carries
kind: :available. Returns slots sorted ascending by start.
Examples
iex> free = ExBooking.Interval.new!(~U[2026-07-13 09:00:00Z], ~U[2026-07-13 10:00:00Z])
...> slots = ExBooking.Slotting.generate_slots(free, 30, 15)
...> Enum.map(slots, & &1.start_at)
[~U[2026-07-13 09:00:00Z], ~U[2026-07-13 09:15:00Z], ~U[2026-07-13 09:30:00Z]]
iex> free = ExBooking.Interval.new!(~U[2026-07-13 09:00:00Z], ~U[2026-07-13 09:20:00Z])
...> ExBooking.Slotting.generate_slots(free, 30, 15)
[]