ExBooking. RRule
(ExBooking v0.1.0)
View Source
Small RFC 5545 RRULE expander.
ExBooking.RRule supports a narrow dependency-free subset for common daily
and weekly recurrences: FREQ, INTERVAL, COUNT, UTC UNTIL, and weekly
BYDAY. Unsupported rule parts fail explicitly instead of being ignored.
Example
iex> {:ok, [first, second]} =
...> ExBooking.RRule.expand(
...> "FREQ=DAILY;COUNT=2",
...> ~U[2026-07-13 09:00:00Z],
...> 30,
...> ~U[2026-07-13 00:00:00Z],
...> ~U[2026-07-15 00:00:00Z]
...> )
...>
...> {first.start_at, second.start_at}
{~U[2026-07-13 09:00:00Z], ~U[2026-07-14 09:00:00Z]}
Summary
Functions
Expands rrule into UTC intervals over [from, until].
Parses an RFC 5545 RRULE line or value into the supported subset.
Types
@type frequency() :: :daily | :weekly
Supported recurrence frequency.
@type t() :: %ExBooking.RRule{ byday: [1..7] | nil, count: pos_integer() | nil, freq: frequency(), interval: pos_integer(), until: DateTime.t() | nil }
Parsed RRULE subset.
Functions
@spec expand( String.t() | t(), DateTime.t(), pos_integer(), DateTime.t(), DateTime.t() ) :: {:ok, [ExBooking.Interval.t()]} | {:error, term()}
Expands rrule into UTC intervals over [from, until].
dtstart supplies the first occurrence start. duration_min supplies each
occurrence duration. The returned intervals are sorted ascending.
Example
iex> {:ok, [first]} =
...> ExBooking.RRule.expand(
...> "FREQ=DAILY;COUNT=1",
...> ~U[2026-07-13 09:00:00Z],
...> 30,
...> ~U[2026-07-13 00:00:00Z],
...> ~U[2026-07-14 00:00:00Z]
...> )
...>
...> first.end_at
~U[2026-07-13 09:30:00Z]
Parses an RFC 5545 RRULE line or value into the supported subset.
Example
iex> {:ok, rule} = ExBooking.RRule.parse("FREQ=WEEKLY;BYDAY=MO,WE")
...> {rule.freq, rule.byday}
{:weekly, [1, 3]}