Tempo.Holidays

Public holidays for every territory as Tempo recurrences, for any window. tempo_holidays reads the date-holidays dataset, every holiday of every type in 207 territories and their subdivisions, with Tempo's reader of its rule grammar, so a holiday is a rule — "Christmas is the 25th of December", "Eid al-Fitr is the 1st of Shawwal" — that gives the days it falls on in any year, and meets anything else in Tempo through set algebra.

Features

Supported Elixir and OTP versions

tempo_holidays supports Elixir 1.17 and later on OTP 27 and later; OTP 26 is not supported, because Tempo requires OTP 27.

Installation

Add tempo_holidays to the dependencies in mix.exs:

def deps do
  [
    {:tempo_holidays, "~> 0.1"}
  ]
end

tempo_holidays reads a zone through the time zone database Tempo asks, Tempo.time_zone_database/0. Tempo comes with Tz and asks it where nothing else is configured, so no configuration is needed. An application that names a database for Tempo with config :ex_tempo, :time_zone_database must name one that knows named zones: tempo_holidays refuses to start with Calendar.UTCOnlyTimeZoneDatabase.

Quick start

A territory's holidays are a set of recurrences; the days they fall on in a year are that year's holidays:

iex> import Tempo.Sigils
iex> {:ok, holidays} = Tempo.Holidays.holidays(:AU, include: :public)
iex> {:ok, this_year} = Tempo.to_interval(holidays, within: ~o"2026")
iex> Tempo.IntervalSet.count(this_year)
9
iex> names = Tempo.IntervalSet.map(this_year, &Tempo.metadata(&1).name)
iex> Enum.take(names, 3)
["New Year's Day", "Australia Day", "Good Friday"]

"Australia's public holidays are rules; this year's are the nine days they fall on in 2026, the first of them New Year's Day."

A holiday of your own is a rule in the same grammar, and the business days of a period are its days less the weekend and the holidays:

iex> import Tempo.Sigils
iex> {:ok, brazil} = Tempo.Holidays.holidays(:BR, include: [:public, :bank])
iex> {:ok, anbima} = Tempo.Holidays.remove(brazil, "Election Day")
iex> {:ok, weekends} = Tempo.weekends(:BR)
iex> {:ok, business_days} = Tempo.difference(~o"2026-01-02/2026-03-31", [weekends, anbima])
iex> Tempo.count(business_days, :day)
{:ok, 61}

"Brazil's public and bank holidays without Election Day are ANBIMA's calendar, and the business days of the first quarter from the 2nd of January are 61."

Documentation

Full API documentation is available on HexDocs.

License

The code is licensed under the Apache License 2.0; see LICENSE.md. The holiday data derives from date-holidays and is redistributed under CC-BY-SA-3.0; see NOTICE.