# `Calendrical.Month`

The months of any calendar, computed once for every calendar from its
kernel: how a month is named and numbered, which months a year has and
which days a month has, and the lengths a month can have.

A date's month is its position in the year. A calendar names that
position in two ways. Its traditional number is the number the culture
gives the month, `n`, or `{n, :leap}` for an intercalary month that
follows month `n`: in a Chinese year whose leap month follows month 2,
position 3 is `{2, :leap}` and position 4 is `3`, and in a Hebrew leap
year position 6, Adar I, is `{5, :leap}`. It follows from one fact the
calendar states, the position of its leap month
(`c:Calendrical.leap_month/1`). Its CLDR month is the index of its name
in the calendar's CLDR data, which is the month a date is written with
(`c:Calendrical.written_date/3`) in every CLDR calendar but the Hebrew,
where CLDR gives Adar I a number of its own, so that from Adar on a
month of an ordinary year is named one more than its place.

Every function here takes the calendar as its first argument and
answers for every calendar Calendrical builds. The calendar modules
carry a delegation to each.

# `calendar`

```elixir
@type calendar() :: module()
```

A calendar module.

# `lengths`

```elixir
@type lengths() :: Calendrical.Info.month_lengths()
```

The lengths a month can have, by month: a count of days, a range of them, or a list of them (`t:Calendrical.Info.month_lengths/0`).

# `traditional_month`

```elixir
@type traditional_month() :: Calendar.month() | {Calendar.month(), :leap}
```

A month as a culture names it: its number, or `{number, :leap}` for a leap month.

# `cldr_month`

```elixir
@spec cldr_month(calendar(), Calendar.month()) :: traditional_month()
```

Returns the CLDR month a month of the year names without a year: the
name the month carries in the year that holds 1 January 2000, which is
every year's in a calendar whose months are named alike in every year.
A Hebrew month is its own number, since which name a place carries
there depends on the year.

### Arguments

* `calendar` is a calendar module.

* `month` is a month of the calendar.

### Returns

* A CLDR month number, or the month itself where the calendar has no
  such month in the reference year.

### Examples

    iex> {:ok, us} = Calendrical.FiscalYear.calendar_for(:US)
    iex> Calendrical.Month.cldr_month(us, 1)
    10

    iex> Calendrical.Month.cldr_month(Calendrical.Gregorian, 7)
    7

# `cldr_month`

```elixir
@spec cldr_month(calendar(), Calendar.year(), Calendar.month()) ::
  traditional_month() | {:error, Exception.t()}
```

Returns the CLDR month of a month of a year: the index of its name in
the calendar's CLDR data, with `{month, :leap}` where the name has a
leap form.

### Arguments

* `calendar` is a calendar module.

* `year` and `month` are a month of the calendar.

### Returns

* A CLDR month number, or `{month, :leap}`, or

* `{:error, exception}` for a month the year does not have.

### Examples

    # Nisan, the seventh month of an ordinary Hebrew year, is CLDR's month 8
    iex> Calendrical.Month.cldr_month(Calendrical.Hebrew, 5786, 7)
    8

    # The leap month after the second month of a Chinese year
    iex> Calendrical.Month.cldr_month(Calendrical.Chinese, 4660, 3)
    {2, :leap}

    # The first month of a fiscal year that begins in October is named October
    iex> {:ok, us} = Calendrical.FiscalYear.calendar_for(:US)
    iex> Calendrical.Month.cldr_month(us, 2026, 1)
    10

# `day_numbers`

```elixir
@spec day_numbers(calendar(), Calendar.year(), Calendar.month()) :: [Range.t()]
```

Returns the days a month of a year has, as runs of their numbers in
order.

### Arguments

* `calendar` is a calendar module.

* `year` and `month` are a month of the calendar.

### Returns

* A list of ranges: one from 1 in every month of every calendar but a
  composite, whose month a change of calendar falls in has the days
  that are left, and `[]` for a month the year does not have.

### Examples

    iex> Calendrical.Month.day_numbers(Calendrical.Gregorian, 2026, 2)
    [1..28]

    # England dropped 3 to 13 September 1752
    iex> Calendrical.Month.day_numbers(Calendrical.Reform.England, 1752, 9)
    [1..2, 14..30]

# `days_in_month`

```elixir
@spec days_in_month(calendar(), Calendar.month()) ::
  Calendar.day()
  | {:ambiguous, Range.t() | [Calendar.day(), ...]}
  | {:error, Exception.t()}
```

Returns the number of days a month of the calendar has without a year:
a count where the month has as many in every year, and
`{:ambiguous, range}` where its length depends on the year.

### Arguments

* `calendar` is a calendar module.

* `month` is a month of the calendar.

### Returns

* A count, `{:ambiguous, range}`, or

* `{:error, %Calendrical.NotDefinedError{}}` for a month the calendar
  has in no year.

### Examples

    iex> Calendrical.Month.days_in_month(Calendrical.Gregorian, 1)
    31

    iex> Calendrical.Month.days_in_month(Calendrical.Gregorian, 2)
    {:ambiguous, 28..29}

# `days_in_month_bounds`

```elixir
@spec days_in_month_bounds(calendar(), Calendar.month()) ::
  {Calendar.day(), Calendar.day()} | {:error, Exception.t()}
```

Returns the fewest and the most days a month of the calendar has in
any year.

### Arguments

* `calendar` is a calendar module.

* `month` is a month of the calendar.

### Returns

* `{fewest, most}`, or

* `{:error, exception}` for a month the calendar has in no year.

### Examples

    iex> Calendrical.Month.days_in_month_bounds(Calendrical.Gregorian, 2)
    {28, 29}

    iex> Calendrical.Month.days_in_month_bounds(Calendrical.Reform.England, 9)
    {19, 30}

# `leap_month`

```elixir
@spec leap_month(calendar(), Calendar.year()) :: Calendar.month() | nil
```

Returns the position of a year's leap month, or `nil` where the year
has none.

### Arguments

* `calendar` is a calendar module.

* `year` is a year of the calendar.

### Returns

* The leap month's position in the year, or `nil`.

### Examples

    iex> Calendrical.Month.leap_month(Calendrical.Hebrew, 5787)
    6

    iex> Calendrical.Month.leap_month(Calendrical.Hebrew, 5786)
    nil

    iex> Calendrical.Month.leap_month(Calendrical.Gregorian, 2026)
    nil

# `lengths`

```elixir
@spec lengths(calendar()) :: lengths()
```

Returns the lengths the months of the calendar can have, by month: the
lengths its `c:Calendrical.info/0` states, or those found by sampling
its years, once, over one cycle of its years where it has one and
otherwise over thirty years from the year that holds 1 January 2000.

### Arguments

* `calendar` is a calendar module.

### Returns

* A `t:lengths/0`.

### Examples

    iex> Calendrical.Month.lengths(Calendrical.Hebrew) |> Map.take([1, 2, 4])
    %{1 => 30, 2 => 29..30, 4 => 29}

# `month_from_traditional`

```elixir
@spec month_from_traditional(calendar(), Calendar.year(), traditional_month()) ::
  Calendar.month() | {:error, Exception.t()}
```

Returns the position in a year of a month the calendar's culture
names: the inverse of `traditional_month/3`.

### Arguments

* `calendar` is a calendar module.

* `year` is a year of the calendar.

* `traditional_month` is a `t:traditional_month/0`.

### Returns

* The month's position in the year, or

* `{:error, exception}` where the year has no such month.

### Examples

    iex> Calendrical.Month.month_from_traditional(Calendrical.Hebrew, 5787, {5, :leap})
    6

    iex> Calendrical.Month.month_from_traditional(Calendrical.Hebrew, 5786, 6)
    6

# `month_numbers`

```elixir
@spec month_numbers(calendar(), Calendar.year()) :: [Range.t()]
```

Returns the months a year has, as runs of their numbers in order.

### Arguments

* `calendar` is a calendar module.

* `year` is a year of the calendar.

### Returns

* A list of ranges: one from 1 in every year of every calendar but a
  composite, whose year a change of calendar falls in has the months
  that are left, and `[]` for a year the calendar does not have.

### Examples

    iex> Calendrical.Month.month_numbers(Calendrical.Hebrew, 5787)
    [1..13]

    # England's 1751 began on 25 March and ended on 31 December
    iex> Calendrical.Month.month_numbers(Calendrical.Reform.England, 1751)
    [3..12]

# `months_in_year_bounds`

```elixir
@spec months_in_year_bounds(calendar()) :: {Calendar.month(), Calendar.month()}
```

Returns the fewest and the most months a year of the calendar has.

### Arguments

* `calendar` is a calendar module.

### Returns

* `{fewest, most}`.

### Examples

    iex> Calendrical.Month.months_in_year_bounds(Calendrical.Hebrew)
    {12, 13}

    iex> Calendrical.Month.months_in_year_bounds(Calendrical.Reform.England)
    {10, 13}

# `named_month`

```elixir
@spec named_month(calendar(), Calendar.year(), Calendar.month()) :: [Date.Range.t()]
```

Returns the days of a named month of a year, in the order of time.

A calendar that counts its months from the year's first day can split
the month that names them: `Calendrical.Julian.March25` begins its year
on 25 March, so its March is two counted months.

### Arguments

* `calendar` is a calendar module.

* `year` is a year of the calendar.

* `named_month` is the CLDR month that names the month.

### Returns

* A list of `t:Date.Range.t/0`, one for each counted month that carries
  the name, earliest first, and `[]` where none does.

### Examples

    iex> Calendrical.Month.named_month(Calendrical.Julian.March25, 1750, 3) |> length()
    2

    iex> Calendrical.Month.named_month(Calendrical.Gregorian, 2026, 2)
    [Date.range(~D[2026-02-01 Calendrical.Gregorian], ~D[2026-02-28 Calendrical.Gregorian])]

# `traditional_leap_month`

```elixir
@spec traditional_leap_month(calendar(), Calendar.year()) :: Calendar.month() | nil
```

Returns the traditional number of the month a year's leap month
follows, or `nil` where the year has none.

### Arguments

* `calendar` is a calendar module.

* `year` is a year of the calendar.

### Returns

* A month number, or `nil`.

### Examples

    iex> Calendrical.Month.traditional_leap_month(Calendrical.Hebrew, 5787)
    5

    iex> Calendrical.Month.traditional_leap_month(Calendrical.Chinese, 4660)
    2

# `traditional_month`

```elixir
@spec traditional_month(calendar(), Calendar.year(), Calendar.month()) ::
  traditional_month() | {:error, Exception.t()}
```

Returns a month of a year as the calendar's culture names it: its
traditional number, or `{month, :leap}` for a leap month.

### Arguments

* `calendar` is a calendar module.

* `year` and `month` are a month of the calendar.

### Returns

* A `t:traditional_month/0`, or

* `{:error, exception}` for a month the year does not have.

### Examples

    # Adar I, the sixth month of the Hebrew leap year 5787, follows Shevat, month 5
    iex> Calendrical.Month.traditional_month(Calendrical.Hebrew, 5787, 6)
    {5, :leap}

    iex> Calendrical.Month.traditional_month(Calendrical.Hebrew, 5787, 7)
    6

# `traditional_months`

```elixir
@spec traditional_months(calendar(), Calendar.year()) :: [traditional_month()]
```

Returns a year's months in order, as the calendar's culture names them.

### Arguments

* `calendar` is a calendar module.

* `year` is a year of the calendar.

### Returns

* A list of `t:traditional_month/0`, the nth naming the year's nth
  month, and `[]` for a year the calendar does not have.

### Examples

    iex> Calendrical.Month.traditional_months(Calendrical.Hebrew, 5787)
    [1, 2, 3, 4, 5, {5, :leap}, 6, 7, 8, 9, 10, 11, 12]

# `written_month_from_cldr_month`

```elixir
@spec written_month_from_cldr_month(calendar(), Calendar.year(), traditional_month()) ::
  traditional_month() | {:error, Exception.t()}
```

Returns the month a CLDR month is written with in a year: the inverse
of `cldr_month/3` for the figures a date is written with.

A month's name and its figure are one number in every calendar but the
Hebrew, where CLDR numbers Nisan 8 in every year and a date writes it
by its place, 7 in an ordinary year.

### Arguments

* `calendar` is a calendar module.

* `year` is a year of the calendar.

* `cldr_month` is a CLDR month number, or `{month, :leap}`.

### Returns

* The month as `c:Calendrical.written_date/3` writes it, or

* `{:error, %Calendrical.InvalidMonthError{}}` where the year has no
  month of that name.

### Examples

    iex> Calendrical.Month.written_month_from_cldr_month(Calendrical.Hebrew, 5786, 8)
    7

    iex> Calendrical.Month.written_month_from_cldr_month(Calendrical.Hebrew, 5787, 8)
    8

    iex> Calendrical.Month.written_month_from_cldr_month(Calendrical.Chinese, 4660, {2, :leap})
    {2, :leap}

    iex> Calendrical.Month.written_month_from_cldr_month(Calendrical.Hebrew, 5786, 6)
    {:error, %Calendrical.InvalidMonthError{calendar: Calendrical.Hebrew, year: 5786, month: 6}}

---

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