# `Calendrical.Hebrew`

Implementation of the Hebrew (Jewish) calendar.

The Hebrew calendar is a *lunisolar* calendar with 12 months in an
ordinary year and 13 months in a leap year. The leap month
(*Adar I*) is inserted before *Adar* (which becomes *Adar II*) in
the 3rd, 6th, 8th, 11th, 14th, 17th and 19th years of each 19-year
*Metonic* cycle.

Year length varies between 353, 354, 355 (ordinary) and 383, 384,
385 (leap) days. The variability comes from two of the twelve
"fixed" months — *Heshvan* (month 2) and *Kislev* (month 3) — which
can each be either 29 or 30 days, plus the *molad of Tishri* delay
rules used to keep the calendar aligned with both the lunar and
solar cycles and to prevent certain holidays from falling on
prohibited days of the week.

## Month numbering

Months are numbered to match the [CLDR Hebrew calendar
convention](https://cldr.unicode.org/), with **Tishri = 1** and the
Hebrew year starting on 1 Tishri. The leap month, *Adar I*, occupies
position 6 and is **only valid in leap years**. In an ordinary year,
month 6 does not exist; the calendar goes directly from 5 (Shevat)
to 7 (Adar).

| # | Name        | Length | Notes |
|---|-------------|--------|-------|
| 1 | Tishri      | 30     | Year start |
| 2 | Heshvan     | 29 / 30 | (long in 355- and 385-day years) |
| 3 | Kislev      | 30 / 29 | (short in 353- and 383-day years) |
| 4 | Tevet       | 29     | |
| 5 | Shevat      | 30     | |
| 6 | Adar I      | 30     | **leap years only** |
| 7 | Adar / Adar II | 29  | "Adar" in ordinary years; "Adar II" in leap years |
| 8 | Nisan       | 30     | |
| 9 | Iyar        | 29     | |
| 10| Sivan       | 30     | |
| 11| Tamuz       | 29     | |
| 12| Av          | 30     | |
| 13| Elul        | 29     | |

Days are assumed to begin at midnight rather than at sunset.

## Reference

Algorithms are taken from Dershowitz & Reingold, *Calendrical
Calculations* (4th ed.), Chapter 8, "The Hebrew Calendar". Note
that Reingold uses Nisan = 1 month numbering internally, while this
module uses CLDR's Tishri = 1 numbering at the public API; the
conversion is handled transparently.

# `day`

```elixir
@type day() :: 1..30
```

# `month`

```elixir
@type month() :: 1..13
```

# `year`

```elixir
@type year() :: pos_integer()
```

# `calendar_base`

Identifies whether this calendar is month
or week based.

# `calendar_year`

```elixir
@spec calendar_year(Calendar.year(), Calendar.month(), Calendar.day()) ::
  Calendar.year()
```

Returns the calendar year as displayed
on rendered calendars.

# `cldr_calendar_type`

Defines the CLDR calendar type for this calendar.

This type is used in support of `Calendrical.
localize/3`.

# `cyclic_year`

```elixir
@spec cyclic_year(Calendar.year(), Calendar.month(), Calendar.day()) ::
  Calendar.year()
```

Returns the cyclic year as displayed
on rendered calendars.

# `date_from_iso_days`

```elixir
@spec date_from_iso_days(integer()) :: {year(), month(), day()}
```

Returns a Hebrew `{year, month, day}` for the given ISO day number.

# `date_to_iso_days`

```elixir
@spec date_to_iso_days(year(), month(), day()) :: integer()
```

Returns the number of ISO days for the given Hebrew `year`,
`month`, and `day`.

# `day_of_era`

```elixir
@spec day_of_era(Calendar.year(), Calendar.month(), Calendar.day()) ::
  {day :: Calendar.day(), era :: Calendar.era()}
```

Calculates the day and era from the given
`year`, `month`, and `day`.

By default we consider on two eras: before the epoch
and on-or-after the epoch.

# `day_of_year`

```elixir
@spec day_of_year(Calendar.year(), Calendar.month(), Calendar.day()) :: Calendar.day()
```

Calculates the day of the year from the given
`year`, `month`, and `day`.

# `days_in_month`

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

Returns how many days there are in the given month.

Must be implemented in derived calendars because
we cannot know what the calendar format is.

# `days_in_month`

```elixir
@spec days_in_month(Calendar.year(), Calendar.month()) :: Calendar.month()
@spec days_in_month(year(), month()) :: 29..30
```

Returns the number of days in the given Hebrew `year` and `month`.

Returns `{:error, :invalid_month}` if `month` is `6` (Adar I) and
`year` is not a leap year.

# `days_in_week`

Returns the number days in a a week.

# `days_in_year`

```elixir
@spec days_in_year(year()) :: 353..355 | 383..385
```

Returns the total number of days in the given Hebrew `year`.

Possible values are 353, 354, 355 (ordinary years) and 383, 384,
385 (leap years).

# `epoch`

# `epoch_day_of_week`

# `extended_year`

```elixir
@spec extended_year(Calendar.year(), Calendar.month(), Calendar.day()) ::
  Calendar.year()
```

Returns the extended year as displayed
on rendered calendars.

# `first_day_of_week`

# `hebrew_new_year`

```elixir
@spec hebrew_new_year(year()) :: integer()
```

Returns the ISO day number of *1 Tishri* of the given Hebrew `year`
(the start of the Hebrew year).

# `iso_week_of_year`

```elixir
@spec iso_week_of_year(Calendar.year(), Calendar.month(), Calendar.day()) ::
  {:error, :not_defined}
```

Calculates the ISO week of the year from the
given `year`, `month`, and `day`.

By default this function always returns
`{:error, :not_defined}`.

# `last_day_of_week`

# `leap_year?`

```elixir
@spec leap_year?(year()) :: boolean()
```

Returns whether the given Hebrew `year` is a leap year (i.e. it
contains the embolismic month *Adar I*).

Leap years are determined by a 19-year Metonic cycle: years
3, 6, 8, 11, 14, 17, and 19 of each cycle are leap years.

# `month`

Returns a `t:Date.Range.t/0` representing
a given month of a year.

# `month_of_year`

```elixir
@spec month_of_year(Calendar.year(), Calendar.month(), Calendar.day()) ::
  Calendar.month() | {Calendar.month(), Calendrical.leap_month?()}
```

Returns the month of the year for the given Hebrew date.

In a leap year, month 7 is *Adar II* and is returned as
`{7, :leap}` so that `Calendrical.localize/3` picks up the
CLDR `7_yeartype_leap` variant ("Adar II"). All other months
are returned as plain integers.

# `months_in_leap_year`

Returns the number of months in a leap year.

# `months_in_ordinary_year`

Returns the number of months in a normal year.

# `months_in_year`

```elixir
@spec months_in_year(year()) :: 12..13
```

Returns the number of months in the given Hebrew `year` (12 in an
ordinary year, 13 in a leap year).

# `naive_datetime_from_iso_days`

```elixir
@spec naive_datetime_from_iso_days(Calendar.iso_days()) ::
  {Calendar.year(), Calendar.month(), Calendar.day(), Calendar.hour(),
   Calendar.minute(), Calendar.second(), Calendar.microsecond()}
```

Converts the `t:Calendar.iso_days` format to the
datetime format specified by this calendar.

# `naive_datetime_to_iso_days`

```elixir
@spec naive_datetime_to_iso_days(
  Calendar.year(),
  Calendar.month(),
  Calendar.day(),
  Calendar.hour(),
  Calendar.minute(),
  Calendar.second(),
  Calendar.microsecond()
) :: Calendar.iso_days()
```

Returns the `t:Calendar.iso_days` format of
the specified date.

# `periods_in_year`

Returns the number of periods in a given
`year`. A period corresponds to a month
in month-based calendars and a week in
week-based calendars.

# `plus`

Adds an `increment` number of `date_part`s
to a `year-month-day`.

`date_part` can be `:months` only.

# `quarter`

Returns a `t:Date.Range.t/0` representing
a given quarter of a year.

# `quarter_of_year`

```elixir
@spec quarter_of_year(Calendar.year(), Calendar.month(), Calendar.day()) ::
  Calendrical.quarter()
```

The Hebrew calendar does not define quarters because the year has
a variable number of months (12 or 13).

# `related_gregorian_year`

```elixir
@spec related_gregorian_year(Calendar.year(), Calendar.month(), Calendar.day()) ::
  Calendar.year()
```

Returns the related gregorain year as displayed
on rendered calendars.

# `valid_date?`

Determines if the given `year`, `month`, and `day` form a valid
Hebrew date.

Month 6 (*Adar I*) is only valid in leap years.

# `week`

Returns a `t:Date.Range.t/0` representing
a given week of a year.

# `week_of_month`

```elixir
@spec week_of_month(Calendar.year(), Calendar.month(), Calendar.day()) ::
  {pos_integer(), pos_integer()} | {:error, :not_defined}
```

Calculates the week of the year from the given
`year`, `month`, and `day`.

By default this function always returns
`{:error, :not_defined}`.

# `week_of_year`

```elixir
@spec week_of_year(Calendar.year(), Calendar.month(), Calendar.day()) ::
  {:error, :not_defined}
```

Calculates the week of the year from the given
`year`, `month`, and `day`.

By default this function always returns
`{:error, :not_defined}`.

# `weeks_in_year`

Returns the number of weeks in a
given `year`.

# `year`

Returns a `t:Date.Range.t/0` representing
a given year.

# `year_of_era`

```elixir
@spec year_of_era(Calendar.year()) :: {year :: Calendar.year(), era :: Calendar.era()}
```

Calculates the year and era from the given `year`.

# `year_of_era`

```elixir
@spec year_of_era(Calendar.year(), Calendar.month(), Calendar.day()) ::
  {year :: Calendar.year(), era :: Calendar.era()}
```

Calculates the year and era from the given `date`.

---

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