Offlixir (offlixir v0.1.0)

Copy Markdown View Source

Public holidays of European countries, computed offline.

Offlixir keeps the public holidays that apply to the whole country.

Every date returned is a Date struct of the Calendar.ISO calendar.

A country is an ISO 3166-1 alpha-2 code in upper case, as an atom (:FR) or as a string ("FR"). A year is an integer between 1 and 9999.

Observed dates

Some countries move a holiday that falls on a week-end to a working day. A Offlixir.Holiday carries both the calendar date (:date) and the day actually taken off (:observed_date). The functions that return or test plain dates (dates!/2, dates_between!/3, holiday?/2) use the observed date.

Summary

Functions

Returns the supported countries, as upper case atoms in alphabetical order.

Returns the observed dates of the holidays of country for year, in ascending order and without duplicates.

Same as dates/2 but returns the list, or raises ArgumentError.

Returns the observed dates of the holidays of country from from to to, both included, in ascending order and without duplicates.

Returns true when day is the observed date of a holiday of country.

Returns the holidays of country for year, sorted by date.

Same as holidays/2 but returns the list, or raises ArgumentError.

Returns the holidays of country observed from from to to, both included.

Returns true when day falls on the week-end of country.

Types

country()

@type country() :: atom() | String.t()

day()

@type day() :: Date.t() | NaiveDateTime.t() | DateTime.t()

reason()

@type reason() ::
  {:unknown_country, term()}
  | {:invalid_year, term()}
  | {:invalid_range, {Date.t(), Date.t()}}

Functions

countries()

@spec countries() :: [atom()]

Returns the supported countries, as upper case atoms in alphabetical order.

iex> :FR in Offlixir.countries()
true

dates(country, year)

@spec dates(country(), integer()) :: {:ok, [Date.t()]} | {:error, reason()}

Returns the observed dates of the holidays of country for year, in ascending order and without duplicates.

iex> Offlixir.dates(:FR, 2026)
{:ok,
 [~D[2026-01-01], ~D[2026-04-06], ~D[2026-05-01], ~D[2026-05-08], ~D[2026-05-14],
  ~D[2026-05-25], ~D[2026-07-14], ~D[2026-08-15], ~D[2026-11-01], ~D[2026-11-11],
  ~D[2026-12-25]]}

iex> Offlixir.dates(:FR, 10_000)
{:error, {:invalid_year, 10_000}}

dates!(country, year)

@spec dates!(country(), integer()) :: [Date.t()]

Same as dates/2 but returns the list, or raises ArgumentError.

The result is a plain list of Date structs, usable with in:

iex> ~D[2026-07-14] in Offlixir.dates!(:FR, 2026)
true

iex> Offlixir.dates!(:fr, 2026)
** (ArgumentError) unknown country :fr, expected a supported ISO 3166-1 alpha-2 code in upper case such as :FR or "FR"

dates_between!(country, from, to)

@spec dates_between!(country(), day(), day()) :: [Date.t()]

Returns the observed dates of the holidays of country from from to to, both included, in ascending order and without duplicates.

iex> Offlixir.dates_between!(:FR, ~D[2025-12-01], ~D[2026-01-31])
[~D[2025-12-25], ~D[2026-01-01]]

holiday?(day, country)

@spec holiday?(day(), country()) :: boolean()

Returns true when day is the observed date of a holiday of country.

day can be a Date, a NaiveDateTime or a DateTime. Only the date part is read. For a DateTime it is the date in its own time zone.

iex> Offlixir.holiday?(~D[2026-07-14], :FR)
true

iex> Offlixir.holiday?(~N[2026-07-15 08:30:00], "FR")
false

holidays(country, year)

@spec holidays(country(), integer()) ::
  {:ok, [Offlixir.Holiday.t()]} | {:error, reason()}

Returns the holidays of country for year, sorted by date.

Two holidays that fall on the same date are both returned.

iex> {:ok, [first | _]} = Offlixir.holidays(:FR, 2026)
iex> first
%Offlixir.Holiday{
  country: :FR,
  id: "FR-NEWYEARSDAY-01",
  date: ~D[2026-01-01],
  observed_date: ~D[2026-01-01],
  local_name: "Jour de l'an",
  english_name: "New Year's Day"
}

iex> Offlixir.holidays(:XX, 2026)
{:error, {:unknown_country, :XX}}

holidays!(country, year)

@spec holidays!(country(), integer()) :: [Offlixir.Holiday.t()]

Same as holidays/2 but returns the list, or raises ArgumentError.

iex> Offlixir.holidays!("FR", 2026) |> Enum.map(& &1.english_name) |> Enum.take(3)
["New Year's Day", "Easter Monday", "Labour Day"]

holidays_between!(country, from, to)

@spec holidays_between!(country(), day(), day()) :: [Offlixir.Holiday.t()]

Returns the holidays of country observed from from to to, both included.

Raises ArgumentError when the country is unknown, when a year of the range is invalid or when to is before from.

iex> Offlixir.holidays_between!(:FR, ~D[2025-12-01], ~D[2026-01-31]) |> Enum.map(& &1.id)
["FR-CHRISTMASDAY-01", "FR-NEWYEARSDAY-01"]

weekend?(day, country)

@spec weekend?(day(), country()) :: boolean()

Returns true when day falls on the week-end of country.

The week-end is Saturday and Sunday in every supported country.

iex> Offlixir.weekend?(~D[2026-07-11], :FR)
true

iex> Offlixir.weekend?(~D[2026-07-13], :FR)
false