# `Koyomi.Holidays.Rules`
[🔗](https://github.com/hattoriai/koyomi/blob/v0.2.1/lib/koyomi/holidays/rules.ex#L1)

Date rules for holidays: Easter, the nth weekday of a month, and the
days that replace a holiday on a weekend. The built-in countries use
them, and a `Koyomi.Holidays.Provider` can too.

Weekdays are numbered as in `Date.day_of_week/1`: 1 is Monday and 7 is
Sunday.

# `weekday`

```elixir
@type weekday() :: 1..7
```

# `easter`

```elixir
@spec easter(integer()) :: Date.t()
```

Returns Easter Sunday of `year` in the Gregorian calendar (the
Western churches' date), by the anonymous Gregorian computus.

## Examples

    iex> Koyomi.Holidays.Rules.easter(2025)
    ~D[2025-04-20]

# `nth_weekday`

```elixir
@spec nth_weekday(integer(), 1..12, weekday(), pos_integer() | :last) :: Date.t()
```

Returns the `n`th `weekday` of a month, or the last one when `n` is
`:last`.

## Examples

    iex> Koyomi.Holidays.Rules.nth_weekday(2027, 11, 4, 4)
    ~D[2027-11-25]

    iex> Koyomi.Holidays.Rules.nth_weekday(2027, 5, 1, :last)
    ~D[2027-05-31]

# `on_or_after`

```elixir
@spec on_or_after(Date.t(), weekday()) :: Date.t()
```

Returns the first `weekday` on or after `date`.

## Examples

    iex> Koyomi.Holidays.Rules.on_or_after(~D[2027-06-20], 6)
    ~D[2027-06-26]

# `on_or_before`

```elixir
@spec on_or_before(Date.t(), weekday()) :: Date.t()
```

Returns the last `weekday` on or before `date`.

## Examples

    iex> Koyomi.Holidays.Rules.on_or_before(~D[2027-05-24], 1)
    ~D[2027-05-24]

# `substitute_days`

```elixir
@spec substitute_days([Koyomi.Holidays.Provider.entry()], [
  Koyomi.Holidays.Provider.entry()
]) :: [
  {Date.t(), Koyomi.Holidays.Provider.entry()}
]
```

Returns the days that replace holidays on a weekend, as
`{day, holiday}` pairs.

Each holiday of `eligible` on a Saturday or a Sunday, in date order, is
replaced by the next weekday that is neither a holiday of `holidays`
nor a day already given to another holiday. This is the British rule
for substitute days: with Christmas Day on a Saturday and Boxing Day on
the Sunday, the days off are Monday 27 and Tuesday 28 December.

## Examples

    iex> christmas = {~D[2027-12-25], "Christmas Day", "Christmas Day"}
    iex> boxing = {~D[2027-12-26], "Boxing Day", "Boxing Day"}
    iex> Koyomi.Holidays.Rules.substitute_days([christmas, boxing], [christmas, boxing])
    [{~D[2027-12-27], christmas}, {~D[2027-12-28], boxing}]

# `weekend?`

```elixir
@spec weekend?(Date.t()) :: boolean()
```

Returns `true` when `date` is a Saturday or a Sunday.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
