A collection of rules whose occurrences form one set: a territory's public holidays, a calendar's events.
A recurrence set is a Tempo.t/0 of the :all form, so it goes where
any expression goes: Tempo.to_interval/2 gives its occurrences within a
window, and the set operations take it as an operand. Its members are
recurrences (~o"R/../P1Y/FL12M25DN"), intervals and values, each with
the metadata its occurrences carry (a holiday's name), and other sets.
A member may depend on the others. keep_when/2 keeps a member's
occurrences only where the days around them fall on other members'
occurrences (a bridge day), and move_when/2 moves an occurrence that
falls on one (to the next Monday, say).
Summary
Functions
The set with the members a function is truthy for.
A member whose occurrences are kept only when the spans at given offsets from each fall on other members' occurrences: a bridge day between two holidays.
The members of a recurrence set, as they were given.
A member whose occurrence is moved when it falls on another member's occurrence: a holiday that gives way to another and is observed on the next Thursday.
Builds a recurrence set from its members.
new/2, returning the set or raising.
Functions
@spec filter(Tempo.t(), (Tempo.t() -> as_boolean(term()))) :: Tempo.t()
The set with the members a function is truthy for.
Arguments
setis a recurrence set, aTempo.t/0.funis given each member.
Returns
- The set of the members
funis truthy for, asTempo.IntervalSet.filter/2gives it.
Examples
iex> set = Tempo.RecurrenceSet.new!([Tempo.put_metadata(~o"2026-12-25", %{type: :public}), ~o"2026-01-01"])
iex> set |> Tempo.RecurrenceSet.filter(&(Tempo.metadata(&1)[:type] == :public)) |> Tempo.RecurrenceSet.members() |> length()
1
A member whose occurrences are kept only when the spans at given offsets from each fall on other members' occurrences: a bridge day between two holidays.
Arguments
memberis aTempo.t/0: a recurrence, an interval or a value.optionsis a keyword list of options.
Options
:atis a list ofTempo.Duration.t/0offsets from an occurrence's start (~o"-P1D"is the day before); every one must fall on an occurrence. Required.:falls_onis a map another member's occurrence must hold in its metadata (%{type: :public}), or aTempo.t/0whose spans are read instead. Required.:metadatais a map every occurrence of the member carries.
Returns
- A
Tempo.t/0of the:whenform, for a set to hold.
Examples
iex> bridge = Tempo.RecurrenceSet.keep_when(~o"2026-09-22", at: [~o"-P1D", ~o"P1D"], falls_on: %{type: :public})
iex> {:ok, holidays} =
...> Tempo.RecurrenceSet.new([
...> Tempo.put_metadata(~o"2026-09-21", %{type: :public}),
...> Tempo.put_metadata(~o"2026-09-23", %{type: :public}),
...> bridge
...> ])
iex> {:ok, days} = Tempo.to_interval(holidays)
iex> Tempo.IntervalSet.map(days, &Tempo.day/1)
[21, 22, 23]
The members of a recurrence set, as they were given.
Arguments
setis a recurrence set, or a rule on its own, aTempo.t/0.
Returns
- The list of its members, each a
Tempo.t/0; a rule on its own is its one member. A value that is no expression raises aTempo.ConversionError.
Examples
iex> Tempo.RecurrenceSet.members(Tempo.RecurrenceSet.new!([~o"2026-12-25", ~o"2026-01-01"]))
[~o"2026-12-25", ~o"2026-01-01"]
A member whose occurrence is moved when it falls on another member's occurrence: a holiday that gives way to another and is observed on the next Thursday.
Arguments
memberis aTempo.t/0: a recurrence, an interval or a value.optionsis a keyword list of options.
Options
:falls_onis as forkeep_when/2. Required.:to_nextis a selector forTempo.select/3(~o"1K", Monday): the occurrence moves to the first span it gives after the occurrence. Required.:metadatais a map every occurrence of the member carries.
Returns
- A
Tempo.t/0of the:whenform, for a set to hold.
Examples
iex> moved = Tempo.RecurrenceSet.move_when(~o"2026-04-09", falls_on: %{type: :observance}, to_next: ~o"4K")
iex> {:ok, holidays} = Tempo.RecurrenceSet.new([Tempo.put_metadata(~o"2026-04-09", %{type: :observance}), moved])
iex> {:ok, days} = Tempo.to_interval(holidays)
iex> Tempo.IntervalSet.map(days, &Tempo.day/1)
[9, 16]
@spec new([Tempo.t()], keyword()) :: {:ok, Tempo.t()} | {:error, Exception.t()}
Builds a recurrence set from its members.
Arguments
membersis a list ofTempo.t/0: recurrences, intervals, values, sets, and the conditional memberskeep_when/2andmove_when/2build.optionsis a keyword list of options.
Options
:metadatais a map the set carries.
Returns
{:ok, set}, aTempo.t/0of the:allform.{:error, exception}when the members are of several calendars.
Examples
iex> {:ok, holidays} = Tempo.RecurrenceSet.new([~o"R/2026-01-01/P1Y/FL12M25DN", ~o"R/2026-01-01/P1Y/FL1M1DN"])
iex> {:ok, days} = Tempo.to_interval(holidays, within: ~o"2026")
iex> Tempo.IntervalSet.map(days, &Tempo.month/1)
[1, 12]
new/2, returning the set or raising.
Arguments
membersandoptionsare as fornew/2.
Options
- The options of
new/2.
Returns
Examples
iex> Tempo.RecurrenceSet.new!([~o"2026-12-25"]) |> Tempo.RecurrenceSet.members() |> length()
1