Calendrical.Hebrew (Calendrical v2.2.0)

Copy Markdown

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

A Hebrew date's month is the month's position in its year, as it is in every calendar: 1 (Tishri) to 12 (Elul) in an ordinary year, and 1 to 13 in a leap year, whose leap month Adar I is month 6. So Date.new/4, months_in_year/1 and days_in_month/2 agree, and the months of any year are 1..months_in_year(year).

The months from Adar I on therefore sit one place later in a leap year. The traditional numbering names the same month in every year. It follows RFC 7529 (and the monthCode of JavaScript's Temporal): Tishri is 1 and Elul 12, 6 is Adar in an ordinary year and Adar II in a leap year, and Adar I is {5, :leap}, the leap month that follows month

  1. ordinal_month_from_traditional/2 finds a traditional month's position in a year and lunar_month_of_year/2 goes the other way.
MonthOrdinary yearLeap yearTraditionalDays
Tishri11130
Heshvan22229 or 30
Kislev33330 or 29
Tevet44429
Shevat55530
Adar I—6{5, :leap}30
Adar / Adar II67629
Nisan78730
Iyar89829
Sivan910930
Tamuz10111029
Av11121130
Elul12131229

Heshvan is long in 355- and 385-day years, and Kislev is short in 353- and 383-day years.

Month names come from CLDR, whose Hebrew data numbers the months 1 (Tishri) to 13 (Elul) with 6 for Adar I, whether or not the year has it. month_of_year/3 returns that CLDR number, which is how Calendrical.localize/3 names a date's month, and Calendrical.month_names/2 lists the names by it.

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", which numbers the months from Nisan; this module numbers them by their position in the year, from Tishri.

Summary

Types

A traditional Hebrew month (RFC 7529): 1..12, or {5, :leap} for Adar I.

Functions

Adds whole years, quarters or months to the fields of a naive datetime, keeping its time of day: the add/9 callback CalendarInterval steps an interval of a year or a month with. The date moves as shift/6 moves it, clamping the day into a shorter month.

Returns what this calendar's year is built of, :month or :week, as its info/0 states.

Returns the calendar module whose CLDR calendar type is the one given, whichever calendar is asked (Calendrical.calendar_from_cldr_calendar_type/1).

Returns the day a date is written with: the day of its written_date/3.

Returns the CLDR month a month of the year names without a year (Calendrical.Month.cldr_month/2).

Returns the year a date is written with: the year of its written_date/3.

Returns the CLDR calendar type whose data names this calendar's months, days and quarters, as its info/0 states.

Returns the CLDR calendar type whose data names a date's months and days: the member in effect on the date in a composite calendar, and this calendar's own otherwise (Calendrical.Info.cldr_calendar_type/4).

Returns the CLDR month of a month of a year (Calendrical.Month.cldr_month/3).

Returns the cyclic year of a date (Calendrical.Era.cyclic_year/4).

Returns the Hebrew date in effect at a given instant, under a chosen day-start convention.

Returns the date of this calendar that written figures name (date_from_written_date/3), as fields.

Returns the date of a day of a year, counted from the year's first day.

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

Returns the date of a day of a week of a week-year (Calendrical.Week.date_from_week_date/4).

Returns the date of this calendar that written figures name: the inverse of written_date/3, the fields themselves where they are a date.

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

Returns the dates of this calendar, earliest first, whose month and day are those given and that fall in a Gregorian year.

Returns the days a month of a year has, as runs of their numbers (Calendrical.Month.day_numbers/3).

Returns the day of era and era of a date (Calendrical.Era.day_of_era/4).

Returns the day of the year of a date (Calendrical.Period.day_of_year/4).

Returns the number of days in a month without a year (Calendrical.Month.days_in_month/2).

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

Returns the fewest and the most days a month has in any year (Calendrical.Month.days_in_month_bounds/2).

Returns the number of days in a week.

Returns the number of days in a year (Calendrical.Period.days_in_year/2).

Returns the whole number of date_parts from one {year, month, day} to another, as shift/6 adds them.

Returns the epoch of this calendar: the ISO day number of its first day.

Returns the CLDR calendar type that names this calendar's eras, as its info/0 states.

Returns the extended year of a date (Calendrical.Era.extended_year/4).

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

Returns the static facts about this calendar, as Calendrical.Info.t/0.

Returns the ISO 8601 week-year and week of the day a date names (Calendrical.Week.iso_week_of_year/4).

Returns the position of the leap month, Adar I, in a Hebrew year.

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

Returns the traditional month at a position in a year (Calendrical.Month.traditional_month/3), or an error for a place the year does not have.

Returns the days of a month of a year (Calendrical.Period.month/3).

Returns the position of a traditional month in a year (Calendrical.Month.month_from_traditional/3).

Returns the months a year has, as runs of their numbers (Calendrical.Month.month_numbers/2).

Returns the CLDR month of a month of a year: the index of its name in this calendar's CLDR data, with {month, :leap} where the name has a leap form (Calendrical.Month.cldr_month/3).

Returns the number of months in a leap year: the most months a year of this calendar has.

Returns the number of months in an ordinary year: the fewest months a year of this calendar has.

Returns the number of months in a year without a year: the count where every year has as many, {:ambiguous, range} where a leap year has more, and {:error, %Calendrical.NotDefinedError{}} for a composite calendar (Calendrical.Info.months_in_year/1).

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

Returns the fewest and the most months a year has (Calendrical.Month.months_in_year_bounds/1).

Converts ISO days and a day fraction to a naive datetime of this calendar, as Calendar.naive_datetime_from_iso_days/1 asks.

Converts a naive datetime of this calendar to ISO days and a day fraction, as Calendar.naive_datetime_to_iso_days/7 asks.

Returns the days of a named month in a year (Calendrical.Month.named_month/3).

Returns the number a date's month is written with in figures: the month of its written_date/3.

Returns the position in a year of a traditional month (Calendrical.Month.month_from_traditional/3), as {:ok, month}.

Parses a date written in this calendar's own notation.

Parses a naive datetime written in this calendar's own notation.

Parses a UTC datetime written in this calendar's own notation.

Returns the calendar a date written for this calendar is parsed in, as its info/0 states.

Returns the calendars a date written for this calendar may be written in: the members of a composite calendar, and this calendar alone otherwise (Calendrical.Info.parsing_calendars/1).

Returns the number of periods in a year: its months.

Returns the days of a quadrimester of a year (Calendrical.Period.quadrimester/3).

Returns the days of a quarter of a year (Calendrical.Period.quarter/3).

Returns the quarter of the year a date falls in (Calendrical.Period.quarter_of_year/4).

Returns the days of a semester of a year (Calendrical.Period.semester/3).

Returns the date a number of years, quarters, months, weeks or days on from a date of this calendar, by position, with the traditional month kept across years and a day the resulting month lacks clamped to its last day unless clamp: false (Calendrical.Shift.shift/7).

Shifts a date by a duration: its years and months together, as shift/6 adds months, and then its weeks and days.

Shifts a naive datetime by a duration: its date as shift_date/4 shifts it, and its time as Calendar.ISO does.

Returns the day of a solar term of a Gregorian year, reckoned at the place this calendar's info/0 names, or at the Chinese calendar's meridian, the traditional reference, where it names none.

Returns the traditional number of the month a year's leap month follows, or nil (Calendrical.Month.traditional_leap_month/2).

Returns a month of a year as this calendar names it (Calendrical.Month.traditional_month/3).

Returns a year's months in order, named traditionally (Calendrical.Month.traditional_months/2).

Returns whether the given year, month, and day form a valid Hebrew date.

Returns the seven days of a week of a year (Calendrical.Week.week/3).

Returns the week-year, the week and the day of the week of a date (Calendrical.Week.week_date_from_date/4).

Returns the month and the week of the month a date is in (Calendrical.Week.week_of_month/4).

Returns the week-year and the week of the year a date is in (Calendrical.Week.week_of_year/4).

Returns the number of weeks in a week-year (Calendrical.Week.weeks_in_week_year/2).

Returns the number of weeks in a year (Calendrical.Week.weeks_in_year/2).

Returns the weeks of a month of a year in order (Calendrical.Week.weeks_of_month/3).

Returns the figures a date is written with: its own fields, in a calendar whose dates are written as its own.

Returns the days of a year (Calendrical.Period.year/2).

Returns the year of era and era of a year (Calendrical.Era.year_of_era/2).

Returns the year of era and era of a date (Calendrical.Era.year_of_era/4).

Returns the number of years after which this calendar's years repeat, as its info/0 states, or {:error, %Calendrical.NotDefinedError{}}.

Types

day()

@type day() :: 1..30

month()

@type month() :: 1..13

traditional_month()

@type traditional_month() :: 1..12 | {5, :leap}

A traditional Hebrew month (RFC 7529): 1..12, or {5, :leap} for Adar I.

year()

@type year() :: pos_integer()

Functions

add(year, month, day, hour, minute, second, microsecond, atom, step)

Adds whole years, quarters or months to the fields of a naive datetime, keeping its time of day: the add/9 callback CalendarInterval steps an interval of a year or a month with. The date moves as shift/6 moves it, clamping the day into a shorter month.

Arguments

  • year, month and day are the date's fields in this calendar.

  • hour, minute, second and microsecond are the time of day, returned unchanged.

  • precision is :year, :quarter or :month.

  • step is the number of years, quarters or months to add, which may be negative.

Returns

  • {year, month, day, hour, minute, second, microsecond}.

Examples

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> {year, month, day, 12, 30, 0, {0, 0}} =
...>   Calendrical.Hebrew.add(date.year, date.month, date.day, 12, 30, 0, {0, 0}, :month, 1)
iex> {year, month, day} == Calendrical.Hebrew.shift(date.year, date.month, date.day, :months, 1, [])
true

calendar_base()

Returns what this calendar's year is built of, :month or :week, as its info/0 states.

Returns

  • :week for a calendar whose year is built of weeks.

  • :month otherwise.

Examples

iex> Calendrical.Hebrew.calendar_base() in [:month, :week]
true

calendar_from_cldr_calendar_type(calendar_type)

Returns the calendar module whose CLDR calendar type is the one given, whichever calendar is asked (Calendrical.calendar_from_cldr_calendar_type/1).

Arguments

  • calendar_type is a CLDR calendar type as an atom or a string.

Returns

  • {:ok, calendar_module}, or

  • {:error, exception} for a calendar type no calendar module has.

Examples

iex> Calendrical.Hebrew.calendar_from_cldr_calendar_type(:gregorian)
{:ok, Calendrical.Gregorian}

iex> {:error, %Localize.UnknownCalendarError{}} =
...>   Calendrical.Hebrew.calendar_from_cldr_calendar_type(:not_a_calendar)

cardinal_day(year, month, day)

Returns the day a date is written with: the day of its written_date/3.

Arguments

  • year, month and day are a date of this calendar.

Returns

  • The day of the date's written_date/3, or

  • {:error, %Calendrical.InvalidDateError{}} for a date the calendar does not have.

Examples

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> {_year, _month, written_day} = Calendrical.Hebrew.written_date(date.year, date.month, date.day)
iex> Calendrical.Hebrew.cardinal_day(date.year, date.month, date.day) == written_day
true

cardinal_month(month)

Returns the CLDR month a month of the year names without a year (Calendrical.Month.cldr_month/2).

Arguments

  • month is a month of this calendar.

Returns

  • The CLDR month the month is named in the year that holds 1 January 2000, the month itself in the Hebrew calendar, whose names depend on the year, and the month itself where the reference year has no such month.

Examples

iex> {:ok, date} = Date.convert(~D[2000-01-01], Calendrical.Hebrew)
iex> Calendrical.Hebrew.cardinal_month(1) == Calendrical.Hebrew.cldr_month(date.year, 1)
true

cardinal_year(year, month, day)

Returns the year a date is written with: the year of its written_date/3.

Arguments

  • year, month and day are a date of this calendar.

Returns

  • The year of the date's written_date/3, or

  • {:error, %Calendrical.InvalidDateError{}} for a date the calendar does not have.

Examples

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> {written_year, _month, _day} = Calendrical.Hebrew.written_date(date.year, date.month, date.day)
iex> Calendrical.Hebrew.cardinal_year(date.year, date.month, date.day) == written_year
true

cldr_calendar_type()

Returns the CLDR calendar type whose data names this calendar's months, days and quarters, as its info/0 states.

Returns

  • A CLDR calendar type such as :gregorian or :hebrew.

Examples

iex> Calendrical.Hebrew.cldr_calendar_type() == Calendrical.Hebrew.info().cldr_calendar_type
true

cldr_calendar_type(year, month, day)

Returns the CLDR calendar type whose data names a date's months and days: the member in effect on the date in a composite calendar, and this calendar's own otherwise (Calendrical.Info.cldr_calendar_type/4).

Arguments

  • year, month and day are a date of this calendar.

Returns

  • A CLDR calendar type.

Examples

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> in_effect = Calendrical.Info.in_effect(Calendrical.Hebrew, date.year, date.month, date.day)
iex> Calendrical.Hebrew.cldr_calendar_type(date.year, date.month, date.day) == in_effect.cldr_calendar_type()
true

cldr_month(year, month)

Returns the CLDR month of a month of a year (Calendrical.Month.cldr_month/3).

Arguments

  • year and month are a month of this calendar.

Returns

  • A CLDR month number, or {month, :leap} where the month's name has a leap form, or

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

Examples

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> cldr_month = Calendrical.Hebrew.cldr_month(date.year, date.month)
iex> Calendrical.Hebrew.written_month_from_cldr_month(date.year, cldr_month) ==
...>   Calendrical.Hebrew.numeric_month(date.year, date.month, date.day)
true

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> {:error, %Calendrical.InvalidMonthError{}} = Calendrical.Hebrew.cldr_month(date.year, 99)

cyclic_year(year, month, day)

Returns the cyclic year of a date (Calendrical.Era.cyclic_year/4).

Arguments

  • year, month and day are a date of this calendar.

Returns

  • The date's place in the sexagenary cycle, 1 to 60, in an East Asian calendar, and its year in a calendar whose years run in no such cycle, or

  • {:error, %Calendrical.InvalidDateError{}} for a year the calendar does not have, or

  • {:error, exception}, a Calendrical.MissingFieldsError, for no year.

Examples

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> cyclic_year = Calendrical.Hebrew.cyclic_year(date.year, date.month, date.day)
iex> cyclic_year in 1..60 or cyclic_year == date.year
true

iex> {:error, %Calendrical.MissingFieldsError{}} = Calendrical.Hebrew.cyclic_year(nil, 1, 1)

date_at(datetime, options \\ [])

@spec date_at(DateTime.t(), Keyword.t()) :: {:ok, Date.t()} | {:error, Exception.t()}

Returns the Hebrew date in effect at a given instant, under a chosen day-start convention.

The Jewish day begins at sunset — more precisely the date fully changes at nightfall (tzeit hakochavim) — so in the evening the Hebrew date is already the following day. This maps an absolute instant to the Hebrew date, choosing the boundary with the :day_start option. Unlike the Islamic calendars, whose boundary is a fixed canonical city, the Hebrew boundary is the observer's local sunset, so a :location is taken (defaulting to Jerusalem).

For the plain civil-day mapping (the calendar's default), convert a date directly with Date.convert/2 instead.

Arguments

  • datetime is a DateTime.t/0 — an absolute instant. Its own time zone fixes the instant; the day boundary is taken at :location.

Options

  • :location is a Geo.PointZ.t/0 (or Geo.Point.t/0) giving the observer's location. The default is Jerusalem.

  • :day_start selects the moment the Hebrew day begins:

    • :midnight (the default) — 00:00 local time, the ordinary civil-day mapping.

    • :sunset — true sunset (shkiah, upper-limb) at :location.

    • :nightfall — nightfall (tzeit hakochavim), when the sun reaches a chosen depression below the horizon. See :nightfall_angle.

  • :nightfall_angle is the sun's depression below the horizon, in degrees, that defines nightfall for day_start: :nightfall. The default is 8.5 (the common "three small stars" tzeit).

Returns

  • {:ok, date} — a Hebrew Date.t/0.

  • {:error, %Calendrical.InvalidOptionValueError{}} for an invalid :day_start, :nightfall_angle or :location.

  • {:error, %Calendrical.UnsupportedDateRangeError{}} for a date outside the range the calendar or the installed JPL ephemeris covers.

  • {:error, %Calendrical.NoDuskError{}} where the sun does not set, or nightfall does not occur, at the location on that day.

Examples

# Morning in Jerusalem: still the civil-day date.
iex> {:ok, date} = Calendrical.Hebrew.date_at(~U[2025-03-01 06:00:00Z])
iex> date.calendar
Calendrical.Hebrew

date_from_cardinal_date(year, month, day)

Returns the date of this calendar that written figures name (date_from_written_date/3), as fields.

Arguments

  • year, month and day are the figures a date is written with, as written_date/3 returns them.

Returns

  • {year, month, day}, the date of this calendar, or

  • {:error, %Calendrical.InvalidDateError{}} where the figures name no date.

Examples

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> {year, month, day} = Calendrical.Hebrew.written_date(date.year, date.month, date.day)
iex> Calendrical.Hebrew.date_from_cardinal_date(year, month, day) == {date.year, date.month, date.day}
true

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> {:error, %Calendrical.InvalidDateError{}} = Calendrical.Hebrew.date_from_cardinal_date(date.year, 0, 1)

date_from_day_of_year(year, day_of_year)

Returns the date of a day of a year, counted from the year's first day.

Arguments

  • year is a year of this calendar.

  • day_of_year is the day of the year, counted from 1.

Returns

  • A Date.t/0 of this calendar, or

  • {:error, %Calendrical.InvalidDateError{}} for a day the year does not have.

Examples

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> day_of_year = Calendrical.Hebrew.day_of_year(date.year, date.month, date.day)
iex> Calendrical.Hebrew.date_from_day_of_year(date.year, day_of_year) == date
true

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> {:error, %Calendrical.InvalidDateError{}} = Calendrical.Hebrew.date_from_day_of_year(date.year, 1000)

date_from_iso_days(iso_days)

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

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

Arguments

  • iso_days is an integer count of days since the proleptic ISO epoch.

Returns

  • A three-tuple {year, month, day} in the Hebrew calendar.

Examples

iex> Calendrical.Hebrew.date_from_iso_days(739_500)
{5784, 13, 3}

date_from_week_date(week_year, week, day)

Returns the date of a day of a week of a week-year (Calendrical.Week.date_from_week_date/4).

Arguments

  • week_year is a week-year of this calendar.

  • week is a week of the week-year.

  • day is the day of the week, numbered from 1 for the day the calendar's weeks begin on.

Returns

  • A Date.t/0 of this calendar, or

  • {:error, %Calendrical.InvalidDateError{}} where the week has no such day.

Examples

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> {week_year, week, day} = Calendrical.Hebrew.week_date_from_date(date.year, date.month, date.day)
iex> Calendrical.Hebrew.date_from_week_date(week_year, week, day) == date
true

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> {:error, %Calendrical.InvalidDateError{}} = Calendrical.Hebrew.date_from_week_date(date.year, 1, 8)

date_from_written_date(year, month, day)

Returns the date of this calendar that written figures name: the inverse of written_date/3, the fields themselves where they are a date.

Arguments

  • year, month and day are the figures a date is written with, as written_date/3 returns them.

Returns

  • {:ok, {year, month, day}}, the date of this calendar, or

  • {:error, :invalid_date} where the figures name no date.

The reason is an atom, not an exception: Localize's date parser reads it, as Calendrical.date_from_written_date/3 sets out.

Examples

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> {year, month, day} = Calendrical.Hebrew.written_date(date.year, date.month, date.day)
iex> Calendrical.Hebrew.date_from_written_date(year, month, day) == {:ok, {date.year, date.month, date.day}}
true

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> Calendrical.Hebrew.date_from_written_date(date.year, 0, 1)
{:error, :invalid_date}

date_to_iso_days(year, month, day)

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

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

Arguments

  • year is any Hebrew year as an integer.

  • month is the month's position in the year.

  • day is a Hebrew day-of-month.

Returns

  • An integer count of days since the proleptic ISO epoch.

Examples

iex> Calendrical.Hebrew.date_to_iso_days(5785, 1, 1)
739527

dates_in_gregorian_year(gregorian_year, month, day)

Returns the dates of this calendar, earliest first, whose month and day are those given and that fall in a Gregorian year.

Arguments

  • gregorian_year is the Gregorian year to search within.

  • month and day are a month and a day of this calendar.

Returns

  • A list of zero, one or two Date.t/0 of this calendar, earliest first, since this calendar's years and the Gregorian years drift.

Examples

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> date in Calendrical.Hebrew.dates_in_gregorian_year(2024, date.month, date.day)
true

day_numbers(year, month)

Returns the days a month of a year has, as runs of their numbers (Calendrical.Month.day_numbers/3).

Arguments

  • year and month are a month of this 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> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> Calendrical.Hebrew.day_numbers(date.year, date.month) ==
...>   [1..Calendrical.Hebrew.days_in_month(date.year, date.month)//1]
true

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> Calendrical.Hebrew.day_numbers(date.year, 99)
[]

day_of_era(year, month, day)

Returns the day of era and era of a date (Calendrical.Era.day_of_era/4).

Arguments

  • year, month and day are a date of this calendar.

Returns

  • {day_of_era, era}, where the day of the era counts from the era's first day, or

  • {:error, %Calendrical.InvalidDateError{}} for a date the calendar does not have, or

  • {:error, exception}, a Calendrical.MissingFieldsError, for a missing field.

Examples

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> {day_of_era, era} = Calendrical.Hebrew.day_of_era(date.year, date.month, date.day)
iex> {_year_of_era, year_era} = Calendrical.Hebrew.year_of_era(date.year, date.month, date.day)
iex> day_of_era >= 1 and era == year_era
true

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> {:error, %Calendrical.InvalidDateError{}} = Calendrical.Hebrew.day_of_era(date.year, date.month, 0)

day_of_week(year, month, day, starting_on)

Returns the day of the week of a date (Calendrical.Week.day_of_week/5).

Arguments

  • year, month and day are a date of this calendar.

  • starting_on is :default for the day this calendar's weeks begin on, or the name of a weekday, :monday to :sunday.

Returns

  • {day_of_week, 1, 7}, the day numbered from the day the week begins on, or

  • {:error, %Calendrical.InvalidDateError{}} for a date the calendar does not have, or

  • {:error, exception}, a Calendrical.MissingFieldsError, for a missing field.

Examples

# 1 June 2024 is a Saturday
iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> Calendrical.Hebrew.day_of_week(date.year, date.month, date.day, :monday)
{6, 1, 7}

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> {:error, %Calendrical.InvalidDateError{}} = Calendrical.Hebrew.day_of_week(date.year, date.month, 0, :monday)

day_of_year(year, month, day)

Returns the day of the year of a date (Calendrical.Period.day_of_year/4).

Arguments

  • year, month and day are a date of this calendar.

Returns

  • The day of the year, counted from 1 for its first day, or

  • {:error, %Calendrical.InvalidDateError{}} for a date the calendar does not have, or

  • {:error, exception}, a Calendrical.MissingFieldsError, for a missing field.

Examples

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> first_day = Calendrical.Hebrew.year(date.year).first
iex> Calendrical.Hebrew.day_of_year(date.year, date.month, date.day) == Date.diff(date, first_day) + 1
true

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> {:error, %Calendrical.InvalidDateError{}} = Calendrical.Hebrew.day_of_year(date.year, date.month, 0)

days_in_month(month)

Returns the number of days in a month without a year (Calendrical.Month.days_in_month/2).

Arguments

  • month is a month of this calendar.

Returns

  • The number of days where the month has as many in every year, or

  • {:ambiguous, lengths} where its length depends on the year, the lengths a range or, where they are not consecutive, a list, or

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

  • {:error, exception}, a Calendrical.MissingFieldsError, where the month is nil.

Examples

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> {fewest, most} = Calendrical.Hebrew.days_in_month_bounds(date.month)
iex> case Calendrical.Hebrew.days_in_month(date.month) do
...>   days when is_integer(days) -> fewest == days and most == days
...>   {:ambiguous, lengths} -> Enum.min(lengths) == fewest and Enum.max(lengths) == most
...> end
true

iex> {:error, %Calendrical.NotDefinedError{}} = Calendrical.Hebrew.days_in_month(99)

days_in_month(year, month)

@spec days_in_month(Calendar.year(), Calendar.month()) ::
  Calendar.day() | {:error, Exception.t()}
@spec days_in_month(year(), month()) :: 29 | 30 | {:error, Exception.t()}

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

Arguments

  • year is any Hebrew year as an integer.

  • month is the month's position in the year, 1..months_in_year(year).

Returns

  • The number of days in the month, 29 or 30, or

  • {:error, %Calendrical.InvalidMonthError{}} for a month the year does not have, or

  • {:error, %Calendrical.MissingFieldsError{}} where the year or the month is nil.

Examples

iex> Calendrical.Hebrew.days_in_month(5785, 1)
30

# Adar I, the 6th month of the leap year 5784
iex> Calendrical.Hebrew.days_in_month(5784, 6)
30

# Adar, the 6th month of the ordinary year 5785
iex> Calendrical.Hebrew.days_in_month(5785, 6)
29

# An ordinary year has no 13th month
iex> Calendrical.Hebrew.days_in_month(5785, 13)
{:error, %Calendrical.InvalidMonthError{calendar: Calendrical.Hebrew, year: 5785, month: 13}}

days_in_month_bounds(month)

Returns the fewest and the most days a month has in any year (Calendrical.Month.days_in_month_bounds/2).

Arguments

  • month is a month of this calendar.

Returns

  • {fewest, most}, or

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

Examples

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> {fewest, most} = Calendrical.Hebrew.days_in_month_bounds(date.month)
iex> Calendrical.Hebrew.days_in_month(date.year, date.month) in fewest..most
true

iex> {:error, %Calendrical.InvalidMonthError{}} = Calendrical.Hebrew.days_in_month_bounds(99)

days_in_week()

Returns the number of days in a week.

Returns

  • 7.

Examples

iex> Calendrical.Hebrew.days_in_week()
7

days_in_year(year)

Returns the number of days in a year (Calendrical.Period.days_in_year/2).

Arguments

  • year is a year of this calendar.

Returns

  • The number of days, or

  • {:error, %Calendrical.InvalidDateError{}} for a year the calendar does not have, or

  • {:error, exception}, a Calendrical.MissingFieldsError, for no year.

Examples

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> Calendrical.Hebrew.days_in_year(date.year) == Enum.count(Calendrical.Hebrew.year(date.year))
true

iex> {:error, %Calendrical.MissingFieldsError{}} = Calendrical.Hebrew.days_in_year(nil)

diff(from, to, date_part)

@spec diff({year(), month(), day()}, {year(), month(), day()}, atom()) ::
  integer() | {:error, Exception.t()}

Returns the whole number of date_parts from one {year, month, day} to another, as shift/6 adds them.

date_part can be :years, :quarters, :months, :weeks or :days. The count is the largest number shift/6, clamping the day into a shorter month, can add to the earlier date without passing the later one; it is negative when to is before from. Months count a leap year's Adar I, and come from the months elapsed before each year (235 in every 19), so a span of any length costs the same.

Arguments

  • from is the starting {year, month, day}.

  • to is the ending {year, month, day}.

  • date_part is :years, :quarters, :months, :weeks or :days.

Returns

  • The whole number of date_parts from from to to, as an integer, or

  • {:error, %Calendrical.InvalidDateError{}} for a from or to the calendar does not have, {:error, %Calendrical.MissingFieldsError{}} for one missing a field, or {:error, %Calendrical.InvalidPartError{}} for a date_part other than the five.

Examples

# 5784 is a leap year of thirteen months, 5785 an ordinary one
iex> Calendrical.Hebrew.diff({5784, 1, 1}, {5785, 1, 1}, :months)
13

iex> Calendrical.Hebrew.diff({5784, 1, 1}, {5786, 1, 1}, :months)
25

epoch()

Returns the epoch of this calendar: the ISO day number of its first day.

Returns

  • The epoch as an integer number of days since the ISO epoch.

Examples

iex> Calendrical.Hebrew.epoch() |> is_integer()
true

era_calendar_type()

Returns the CLDR calendar type that names this calendar's eras, as its info/0 states.

Returns

  • A CLDR calendar type such as :gregorian or :japanese.

Examples

iex> Calendrical.Hebrew.era_calendar_type() == Calendrical.Hebrew.info().era_calendar_type
true

extended_year(year, month, day)

Returns the extended year of a date (Calendrical.Era.extended_year/4).

Arguments

  • year, month and day are a date of this calendar.

Returns

  • The year numbered without a gap at 0, so that in a calendar with no year 0 the year before 1 is 0, or

  • {:error, %Calendrical.InvalidDateError{}} for a date the calendar does not have, or

  • {:error, exception}, a Calendrical.MissingFieldsError, for no year.

Examples

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> Calendrical.Hebrew.extended_year(date.year, date.month, date.day) == date.year
true

iex> {:error, %Calendrical.MissingFieldsError{}} = Calendrical.Hebrew.extended_year(nil, 1, 1)

hebrew_new_year(year)

@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).

Arguments

  • year is any Hebrew year as an integer.

Returns

  • An integer count of days since the proleptic ISO epoch.

Examples

iex> Calendrical.Hebrew.hebrew_new_year(5785)
739527

info()

Returns the static facts about this calendar, as Calendrical.Info.t/0.

Returns

Examples

iex> Calendrical.Hebrew.info().calendar
Calendrical.Hebrew

iso_week_of_year(year, month, day)

Returns the ISO 8601 week-year and week of the day a date names (Calendrical.Week.iso_week_of_year/4).

Arguments

  • year, month and day are a date of this calendar.

Returns

  • {week_year, week} of ISO 8601, or

  • {:error, exception} for a date the calendar does not have.

Examples

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> Calendrical.Hebrew.iso_week_of_year(date.year, date.month, date.day)
{2024, 22}

leap_month(year)

@spec leap_month(Calendar.year()) :: 6 | nil

Returns the position of the leap month, Adar I, in a Hebrew year.

Arguments

  • year is a Hebrew year as an integer.

Returns

  • 6, the position of Adar I, in a leap year.

  • nil in an ordinary year, or for anything but an integer year.

Examples

iex> Calendrical.Hebrew.leap_month(5784)
6

iex> Calendrical.Hebrew.leap_month(5785)
nil

leap_year?(year)

@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.

Arguments

  • year is any Hebrew year as an integer.

Returns

  • true if the year contains 13 months; otherwise false.

Examples

iex> Calendrical.Hebrew.leap_year?(5784)
true

iex> Calendrical.Hebrew.leap_year?(5785)
false

lunar_month_of_year(year, month)

Returns the traditional month at a position in a year (Calendrical.Month.traditional_month/3), or an error for a place the year does not have.

Arguments

  • year and month are a month of this calendar.

Returns

  • The month's traditional number, or {month, :leap} for a leap month, or

  • {:error, %Calendrical.InvalidMonthError{}} for a month the year does not have.

Examples

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> Calendrical.Hebrew.lunar_month_of_year(date.year, date.month) ==
...>   Calendrical.Hebrew.traditional_month(date.year, date.month)
true

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> {:error, %Calendrical.InvalidMonthError{}} = Calendrical.Hebrew.lunar_month_of_year(date.year, 99)

month(year, month)

Returns the days of a month of a year (Calendrical.Period.month/3).

Arguments

  • year and month are a month of this calendar.

Returns

Examples

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> date in Calendrical.Hebrew.month(date.year, date.month)
true

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> {:error, %Calendrical.InvalidDateError{}} = Calendrical.Hebrew.month(date.year, 99)

month_from_traditional(year, traditional_month)

Returns the position of a traditional month in a year (Calendrical.Month.month_from_traditional/3).

Arguments

  • year is a year of this calendar.

  • traditional_month is a month's traditional number, or {month, :leap} for a leap month.

Returns

  • The month's position in the year, or

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

Examples

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> traditional_month = Calendrical.Hebrew.traditional_month(date.year, date.month)
iex> Calendrical.Hebrew.month_from_traditional(date.year, traditional_month) == date.month
true

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> {:error, %Calendrical.InvalidMonthError{}} = Calendrical.Hebrew.month_from_traditional(date.year, 99)

month_numbers(year)

Returns the months a year has, as runs of their numbers (Calendrical.Month.month_numbers/2).

Arguments

  • year is a year of this 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> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> Calendrical.Hebrew.month_numbers(date.year) == [1..Calendrical.Hebrew.months_in_year(date.year)//1]
true

month_of_year(year, month, day)

Returns the CLDR month of a month of a year: the index of its name in this calendar's CLDR data, with {month, :leap} where the name has a leap form (Calendrical.Month.cldr_month/3).

Arguments

  • year, month and day are a date of this calendar. The year and the day may be nil: a month's name needs only the month.

Returns

  • A CLDR month number, or {month, :leap}, or

  • {:error, %Calendrical.InvalidDateError{}} for a day the month does not have, or

  • {:error, exception} for a month the year does not have, or a Calendrical.MissingFieldsError where the month is nil.

Examples

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> Calendrical.Hebrew.month_of_year(date.year, date.month, date.day) == Calendrical.Hebrew.cldr_month(date.year, date.month)
true

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> {:error, %Calendrical.InvalidDateError{}} = Calendrical.Hebrew.month_of_year(date.year, date.month, 0)

months_in_leap_year()

Returns the number of months in a leap year: the most months a year of this calendar has.

Returns

  • A positive integer.

Examples

iex> Calendrical.Hebrew.months_in_leap_year() >= Calendrical.Hebrew.months_in_ordinary_year()
true

months_in_ordinary_year()

Returns the number of months in an ordinary year: the fewest months a year of this calendar has.

Returns

  • A positive integer.

Examples

iex> Calendrical.Hebrew.months_in_ordinary_year() <= Calendrical.Hebrew.months_in_leap_year()
true

months_in_year()

Returns the number of months in a year without a year: the count where every year has as many, {:ambiguous, range} where a leap year has more, and {:error, %Calendrical.NotDefinedError{}} for a composite calendar (Calendrical.Info.months_in_year/1).

Returns

  • The number of months where every year has as many, or

  • {:ambiguous, fewest..most} where a leap year has more, or

  • {:error, %Calendrical.NotDefinedError{}} for a composite calendar, whose bounds months_in_year_bounds/0 gives.

Examples

iex> case Calendrical.Hebrew.months_in_year() do
...>   months when is_integer(months) -> months == Calendrical.Hebrew.months_in_leap_year()
...>   {:ambiguous, fewest..most//1} -> {fewest, most} == Calendrical.Hebrew.info().months_in_year
...>   {:error, %Calendrical.NotDefinedError{}} -> is_list(Calendrical.Hebrew.info().members)
...> end
true

months_in_year(year)

@spec months_in_year(year()) :: 12..13 | {:error, Exception.t()}

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

Arguments

  • year is any Hebrew year as an integer.

Returns

  • 12 for an ordinary year or 13 for a leap year, or

  • {:error, %Calendrical.MissingFieldsError{}} where year is nil, or

  • {:error, %Calendrical.InvalidDateError{}} where year is no integer.

Examples

iex> Calendrical.Hebrew.months_in_year(5785)
12

iex> Calendrical.Hebrew.months_in_year(5784)
13

months_in_year_bounds()

Returns the fewest and the most months a year has (Calendrical.Month.months_in_year_bounds/1).

Returns

  • {fewest, most}, which in a composite calendar counts the months left in a year a change of calendar falls in.

Examples

iex> {fewest, most} = Calendrical.Hebrew.months_in_year_bounds()
iex> fewest <= Calendrical.Hebrew.months_in_ordinary_year() and
...>   most >= Calendrical.Hebrew.months_in_leap_year()
true

naive_datetime_from_iso_days(arg)

Converts ISO days and a day fraction to a naive datetime of this calendar, as Calendar.naive_datetime_from_iso_days/1 asks.

Arguments

  • iso_days is {days, {parts_in_day, parts_per_day}}, a day and a fraction of it.

Returns

  • {year, month, day, hour, minute, second, microsecond} of this calendar.

Examples

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> {year, month, day, 12, 0, 0, {0, 6}} =
...>   Calendrical.Hebrew.naive_datetime_from_iso_days({739403, {43200000000, 86400000000}})
iex> {year, month, day} == {date.year, date.month, date.day}
true

naive_datetime_to_iso_days(year, month, day, hour, minute, second, microsecond)

Converts a naive datetime of this calendar to ISO days and a day fraction, as Calendar.naive_datetime_to_iso_days/7 asks.

Arguments

  • year, month and day are a date of this calendar.

  • hour, minute, second and microsecond are a time of day, the microsecond as {microseconds, precision}.

Returns

  • {iso_days, {parts_in_day, parts_per_day}}.

Examples

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> Calendrical.Hebrew.naive_datetime_to_iso_days(date.year, date.month, date.day, 12, 0, 0, {0, 6})
{739403, {43200000000, 86400000000}}

named_month(year, named_month)

Returns the days of a named month in a year (Calendrical.Month.named_month/3).

Arguments

  • year is a year of this calendar.

  • named_month is the CLDR month that names the month.

Returns

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

Examples

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> cldr_month = Calendrical.Hebrew.cldr_month(date.year, date.month)
iex> Calendrical.Hebrew.named_month(date.year, cldr_month) |> Enum.any?(&(date in &1))
true

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> Calendrical.Hebrew.named_month(date.year, 99)
[]

numeric_month(year, month, day)

Returns the number a date's month is written with in figures: the month of its written_date/3.

Arguments

  • year, month and day are a date of this calendar.

Returns

  • The month of the date's written_date/3: a month number, or {month, :leap} for a leap month of a lunisolar calendar, or

  • {:error, %Calendrical.InvalidDateError{}} for a date the calendar does not have.

Examples

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> {_year, written_month, _day} = Calendrical.Hebrew.written_date(date.year, date.month, date.day)
iex> Calendrical.Hebrew.numeric_month(date.year, date.month, date.day) == written_month
true

ordinal_month_from_traditional(year, traditional_month)

Returns the position in a year of a traditional month (Calendrical.Month.month_from_traditional/3), as {:ok, month}.

Arguments

  • year is a year of this calendar.

  • traditional_month is a month's traditional number, or {month, :leap} for a leap month.

Returns

  • {:ok, month}, the month's position in the year, or

  • {:error, %Calendrical.InvalidMonthError{}} for a month or a leap month the year does not have.

Examples

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> traditional_month = Calendrical.Hebrew.traditional_month(date.year, date.month)
iex> Calendrical.Hebrew.ordinal_month_from_traditional(date.year, traditional_month) == {:ok, date.month}
true

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> {:error, %Calendrical.InvalidMonthError{}} = Calendrical.Hebrew.ordinal_month_from_traditional(date.year, 99)

parse_date(string)

Parses a date written in this calendar's own notation.

Arguments

  • string is a date written YYYY-MM-DD, with a leading - for a year before 1, or, in a calendar of weeks, YYYY-Www-D.

Returns

  • {:ok, {year, month, day}}, or

  • {:error, :invalid_format} where the text is not in that form or its fields are not digits, or

  • {:error, :invalid_date} where the text names no date of this calendar.

The reason is an atom, not an exception, because Calendar.parse_date/1 requires one: Date.from_iso8601/2 reads it.

Examples

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> Calendrical.Hebrew.parse_date(Date.to_string(date)) == {:ok, {date.year, date.month, date.day}}
true

iex> Calendrical.Hebrew.parse_date("not a date")
{:error, :invalid_format}

parse_naive_datetime(string)

Parses a naive datetime written in this calendar's own notation.

Arguments

  • string is a date as parse_date/1 reads it, then T or a space and a time of day.

Returns

  • {:ok, {year, month, day, hour, minute, second, microsecond}}, or

  • {:error, reason}, such as :invalid_format or :invalid_date, where the text is no such datetime.

The reason is an atom, not an exception, because Calendar.parse_naive_datetime/1 requires one: NaiveDateTime.from_iso8601/2 reads it.

Examples

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> Calendrical.Hebrew.parse_naive_datetime(Date.to_string(date) <> "T12:00:00") ==
...>   {:ok, {date.year, date.month, date.day, 12, 0, 0, {0, 0}}}
true

iex> Calendrical.Hebrew.parse_naive_datetime("2024-06-01")
{:error, :invalid_format}

parse_utc_datetime(string)

Parses a UTC datetime written in this calendar's own notation.

Arguments

  • string is a date as parse_date/1 reads it, then T or a space, a time of day and an offset from UTC, Z or ±HH:MM.

Returns

  • {:ok, {year, month, day, hour, minute, second, microsecond}, offset}, the datetime in UTC and the offset in seconds it was written with, or

  • {:error, reason}, such as :invalid_format, :invalid_date or :missing_offset, where the text is no such datetime.

The reason is an atom, not an exception, because Calendar.parse_utc_datetime/1 requires one: DateTime.from_iso8601/2 reads it.

Examples

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> Calendrical.Hebrew.parse_utc_datetime(Date.to_string(date) <> "T12:00:00Z") ==
...>   {:ok, {date.year, date.month, date.day, 12, 0, 0, {0, 0}}, 0}
true

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> Calendrical.Hebrew.parse_utc_datetime(Date.to_string(date) <> "T12:00:00")
{:error, :missing_offset}

parsing_calendar()

Returns the calendar a date written for this calendar is parsed in, as its info/0 states.

Returns

  • A calendar module.

Examples

iex> Calendrical.Hebrew.parsing_calendar() == Calendrical.Hebrew.info().parsing_calendar
true

parsing_calendars()

Returns the calendars a date written for this calendar may be written in: the members of a composite calendar, and this calendar alone otherwise (Calendrical.Info.parsing_calendars/1).

Returns

  • A non-empty list of calendar modules, the members of a composite calendar in the order they take effect.

Examples

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> in_effect = Calendrical.Info.in_effect(Calendrical.Hebrew, date.year, date.month, date.day)
iex> in_effect in Calendrical.Hebrew.parsing_calendars()
true

periods_in_year(year)

Returns the number of periods in a year: its months.

Arguments

  • year is a year of this calendar.

Returns

Examples

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> Calendrical.Hebrew.periods_in_year(date.year) == Calendrical.Hebrew.months_in_year(date.year)
true

quadrimester(year, quadrimester)

Returns the days of a quadrimester of a year (Calendrical.Period.quadrimester/3).

Arguments

  • year is a year of this calendar.

  • quadrimester is the quadrimester, 1 to 3.

Returns

  • A Date.Range.t/0, or

  • {:error, %Calendrical.InvalidDateError{}} for a quadrimester or a year the calendar does not have, or

  • {:error, %Calendrical.MissingFieldsError{}} where the year or the quadrimester is nil.

Examples

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> Calendrical.Hebrew.quadrimester(date.year, 1).first == Calendrical.Hebrew.year(date.year).first
true

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> {:error, %Calendrical.InvalidDateError{}} = Calendrical.Hebrew.quadrimester(date.year, 4)

quarter(year, quarter)

Returns the days of a quarter of a year (Calendrical.Period.quarter/3).

Arguments

  • year is a year of this calendar.

  • quarter is the quarter, 1 to 4.

Returns

  • A Date.Range.t/0, or

  • {:error, %Calendrical.InvalidDateError{}} for a quarter or a year the calendar does not have, or

  • {:error, %Calendrical.MissingFieldsError{}} where the year or the quarter is nil.

Examples

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> quarter = Calendrical.Hebrew.quarter_of_year(date.year, date.month, date.day)
iex> date in Calendrical.Hebrew.quarter(date.year, quarter)
true

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> {:error, %Calendrical.InvalidDateError{}} = Calendrical.Hebrew.quarter(date.year, 5)

quarter_of_year(year, month, day)

Returns the quarter of the year a date falls in (Calendrical.Period.quarter_of_year/4).

Arguments

  • year, month and day are a date of this calendar.

Returns

  • The quarter, 1 to 4, or

  • {:error, %Calendrical.InvalidDateError{}} for a date the calendar does not have, or

  • {:error, exception}, a Calendrical.MissingFieldsError, for a missing year or month.

Examples

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> Calendrical.Hebrew.quarter_of_year(date.year, date.month, date.day) in 1..4
true

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> {:error, %Calendrical.InvalidDateError{}} = Calendrical.Hebrew.quarter_of_year(date.year, date.month, 0)

semester(year, semester)

Returns the days of a semester of a year (Calendrical.Period.semester/3).

Arguments

  • year is a year of this calendar.

  • semester is the semester, 1 or 2.

Returns

  • A Date.Range.t/0, or

  • {:error, %Calendrical.InvalidDateError{}} for a semester or a year the calendar does not have, or

  • {:error, %Calendrical.MissingFieldsError{}} where the year or the semester is nil.

Examples

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> Calendrical.Hebrew.semester(date.year, 1).first == Calendrical.Hebrew.year(date.year).first
true

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> {:error, %Calendrical.InvalidDateError{}} = Calendrical.Hebrew.semester(date.year, 3)

shift(year, month, day, date_part, increment, options \\ [])

Returns the date a number of years, quarters, months, weeks or days on from a date of this calendar, by position, with the traditional month kept across years and a day the resulting month lacks clamped to its last day unless clamp: false (Calendrical.Shift.shift/7).

Arguments

  • year, month and day are a date of this calendar.

  • date_part is one of :years, :quarters, :months, :weeks or :days.

  • increment is the number of units, which may be negative.

  • options is a keyword list of options.

Options

  • :clamp is whether a day the resulting month lacks becomes its last day. The default is true.

Returns

  • {year, month, day} of this calendar, or

  • {:error, %Calendrical.InvalidDateError{}} where year, month and day are no date of this calendar, or

  • {:error, %Calendrical.MissingFieldsError{}} where a field is nil.

Examples

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> Calendrical.Hebrew.shift(date.year, date.month, date.day, :days, 0)
{date.year, date.month, date.day}

shift_date(year, month, day, duration)

Shifts a date by a duration: its years and months together, as shift/6 adds months, and then its weeks and days.

Arguments

  • year, month and day are a date of this calendar.

  • duration is a Duration.t/0.

Returns

  • {year, month, day} of this calendar.

Examples

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> {year, month, day} = Calendrical.Hebrew.shift_date(date.year, date.month, date.day, Duration.new!(day: 7))
iex> Date.new!(year, month, day, Calendrical.Hebrew) == Date.add(date, 7)
true

shift_naive_datetime(year, month, day, hour, minute, second, microsecond, duration)

Shifts a naive datetime by a duration: its date as shift_date/4 shifts it, and its time as Calendar.ISO does.

Arguments

  • year, month and day are a date of this calendar.

  • hour, minute, second and microsecond are a time of day, the microsecond as {microseconds, precision}.

  • duration is a Duration.t/0.

Returns

  • {year, month, day, hour, minute, second, microsecond} of this calendar.

Examples

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> next_day = Date.add(date, 1)
iex> Calendrical.Hebrew.shift_naive_datetime(date.year, date.month, date.day, 23, 0, 0, {0, 0}, Duration.new!(hour: 2)) ==
...>   {next_day.year, next_day.month, next_day.day, 1, 0, 0, {0, 0}}
true

shift_time(hour, minute, second, microsecond, duration)

Shifts a time by a duration, as Calendar.ISO does.

Arguments

  • hour, minute, second and microsecond are a time of day, the microsecond as {microseconds, precision}.

  • duration is a Duration.t/0 of time units.

Returns

  • {hour, minute, second, microsecond}, wrapped around midnight.

Examples

iex> Calendrical.Hebrew.shift_time(23, 0, 0, {0, 0}, Duration.new!(hour: 2))
{1, 0, 0, {0, 0}}

solar_term(index, gregorian_year)

Returns the day of a solar term of a Gregorian year, reckoned at the place this calendar's info/0 names, or at the Chinese calendar's meridian, the traditional reference, where it names none.

Arguments

  • index is the solar term's number, 1 (lichun, 315° of solar longitude) to 24, every 15° on.

  • gregorian_year is a Gregorian year.

Returns

Examples

# Qingming, the fifth solar term
iex> Calendrical.Hebrew.solar_term(5, 2025)
{:ok, ~D[2025-04-04 Calendrical.Gregorian]}

iex> Calendrical.Hebrew.solar_term(25, 2025)
{:error, %Calendrical.InvalidSolarTermError{index: 25}}

traditional_leap_month(year)

Returns the traditional number of the month a year's leap month follows, or nil (Calendrical.Month.traditional_leap_month/2).

Arguments

  • year is a year of this calendar.

Returns

  • The traditional number of the month the leap month follows, or

  • nil where the year has no leap month.

Examples

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> is_nil(Calendrical.Hebrew.traditional_leap_month(date.year)) ==
...>   is_nil(Calendrical.Hebrew.leap_month(date.year))
true

traditional_month(year, month)

Returns a month of a year as this calendar names it (Calendrical.Month.traditional_month/3).

Arguments

  • year and month are a month of this calendar.

Returns

  • The month's traditional number, or {month, :leap} for a leap month, or

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

Examples

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> Calendrical.Hebrew.traditional_month(date.year, date.month) ==
...>   Enum.at(Calendrical.Hebrew.traditional_months(date.year), date.month - 1)
true

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> {:error, %Calendrical.InvalidMonthError{}} = Calendrical.Hebrew.traditional_month(date.year, 99)

traditional_months(year)

Returns a year's months in order, named traditionally (Calendrical.Month.traditional_months/2).

Arguments

  • year is a year of this calendar.

Returns

  • A list of traditional months, the nth naming the year's nth month, with {month, :leap} for a leap month, and [] for a year the calendar does not have.

Examples

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> length(Calendrical.Hebrew.traditional_months(date.year)) ==
...>   Calendrical.Hebrew.months_in_year(date.year)
true

valid_date?(year, month, day)

@spec valid_date?(year(), month(), day()) :: boolean()

Returns whether the given year, month, and day form a valid Hebrew date.

An ordinary year has 12 months and a leap year 13.

Arguments

  • year is any Hebrew year as an integer.

  • month is the month's position in the year.

  • day is a Hebrew day-of-month.

Returns

  • true if the date is valid; otherwise false.

Examples

iex> Calendrical.Hebrew.valid_date?(5785, 1, 30)
true

# Elul, the 13th month of the leap year 5784
iex> Calendrical.Hebrew.valid_date?(5784, 13, 1)
true

# An ordinary year has no 13th month
iex> Calendrical.Hebrew.valid_date?(5785, 13, 1)
false

week(year, week)

Returns the seven days of a week of a year (Calendrical.Week.week/3).

Arguments

  • year is a year of this calendar.

  • week is a week of the year.

Returns

  • A Date.Range.t/0 of the week's seven days, which may begin in the year before or end in the year after, or

  • {:error, %Calendrical.InvalidDateError{}} for a week the year does not have, or

  • {:error, %Calendrical.MissingFieldsError{}} where the year or the week is nil.

Examples

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> {week_year, week} = Calendrical.Hebrew.week_of_year(date.year, date.month, date.day)
iex> days = Calendrical.Hebrew.week(week_year, week)
iex> {Enum.count(days), date in days}
{7, true}

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> {:error, %Calendrical.InvalidDateError{}} = Calendrical.Hebrew.week(date.year, 0)

week_date_from_date(year, month, day)

Returns the week-year, the week and the day of the week of a date (Calendrical.Week.week_date_from_date/4).

Arguments

  • year, month and day are a date of this calendar.

Returns

  • {week_year, week, day_of_week}, the day numbered from the day the calendar's weeks begin on, or

  • {:error, %Calendrical.InvalidDateError{}} for a date the calendar does not have.

Examples

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> {week_year, week, day} = Calendrical.Hebrew.week_date_from_date(date.year, date.month, date.day)
iex> {week_year, week} == Calendrical.Hebrew.week_of_year(date.year, date.month, date.day) and day in 1..7
true

week_of_month(year, month, day)

Returns the month and the week of the month a date is in (Calendrical.Week.week_of_month/4).

Arguments

  • year, month and day are a date of this calendar.

Returns

  • {month, week}, where the month is the one before or after where the date falls in that month's last or first week, or

  • {:error, exception} for a date the calendar does not have.

Examples

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> {month, week} = Calendrical.Hebrew.week_of_month(date.year, date.month, date.day)
iex> month in (date.month - 1)..(date.month + 1) and week >= 1
true

week_of_year(year, month, day)

Returns the week-year and the week of the year a date is in (Calendrical.Week.week_of_year/4).

Arguments

  • year, month and day are a date of this calendar.

Returns

  • {week_year, week}, where the week-year is the year before or after where the date falls in that year's last or first week, or

  • {:error, exception} for a date the calendar does not have: a Calendrical.MissingFieldsError for a date missing a field, and a Calendrical.InvalidDateError otherwise.

Examples

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> {week_year, week} = Calendrical.Hebrew.week_of_year(date.year, date.month, date.day)
iex> date in Calendrical.Hebrew.week(week_year, week)
true

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> {:error, %Calendrical.InvalidDateError{}} = Calendrical.Hebrew.week_of_year(date.year, date.month, 0)

weeks_in_week_year(week_year)

Returns the number of weeks in a week-year (Calendrical.Week.weeks_in_week_year/2).

Arguments

  • week_year is a week-year of this calendar.

Returns

  • The number of weeks, or

  • {:error, %Calendrical.InvalidDateError{}} for a year the calendar does not have.

Examples

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> {week_year, week, _day} = Calendrical.Hebrew.week_date_from_date(date.year, date.month, date.day)
iex> week <= Calendrical.Hebrew.weeks_in_week_year(week_year)
true

weeks_in_year(year)

Returns the number of weeks in a year (Calendrical.Week.weeks_in_year/2).

Arguments

  • year is a year of this calendar.

Returns

  • The number of weeks, or

  • {:error, exception} for a year the calendar does not have.

Examples

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> {week_year, week} = Calendrical.Hebrew.week_of_year(date.year, date.month, date.day)
iex> week <= Calendrical.Hebrew.weeks_in_year(week_year)
true

weeks_of_month(year, month)

Returns the weeks of a month of a year in order (Calendrical.Week.weeks_of_month/3).

Arguments

  • year and month are a month of this calendar.

Returns

  • A list of Date.Range.t/0, one for each week week_of_month/3 names for the month, the first of which may begin in the month before and the last run into the month after, or

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

Examples

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> Calendrical.Hebrew.weeks_of_month(date.year, date.month) |> Enum.all?(&(Enum.count(&1) == 7))
true

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> {:error, %Calendrical.InvalidMonthError{}} = Calendrical.Hebrew.weeks_of_month(date.year, 99)

written_date(year, month, day)

Returns the figures a date is written with: its own fields, in a calendar whose dates are written as its own.

Arguments

  • year, month and day are a date of this calendar.

Returns

  • {year, month, day} as the date is written, where the month of a lunisolar calendar is its traditional number, {month, :leap} for a leap month.

Examples

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> {year, month, day} = Calendrical.Hebrew.written_date(date.year, date.month, date.day)
iex> Calendrical.Hebrew.date_from_written_date(year, month, day) == {:ok, {date.year, date.month, date.day}}
true

written_month_from_cldr_month(year, cldr_month)

Returns the month a CLDR month is written with in a year (Calendrical.Month.written_month_from_cldr_month/3).

Arguments

  • year is a year of this calendar.

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

Returns

Examples

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> {_year, written_month, _day} = Calendrical.Hebrew.written_date(date.year, date.month, date.day)
iex> cldr_month = Calendrical.Hebrew.cldr_month(date.year, date.month)
iex> Calendrical.Hebrew.written_month_from_cldr_month(date.year, cldr_month) == written_month
true

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> Calendrical.Hebrew.written_month_from_cldr_month(date.year, 99)
{:error, :invalid_month}

year(year)

Returns the days of a year (Calendrical.Period.year/2).

Arguments

  • year is a year of this calendar.

Returns

Examples

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> date in Calendrical.Hebrew.year(date.year)
true

iex> {:error, %Calendrical.MissingFieldsError{}} = Calendrical.Hebrew.year(nil)

year_of_era(year)

Returns the year of era and era of a year (Calendrical.Era.year_of_era/2).

Arguments

  • year is a year of this calendar.

Returns

  • {year_of_era, era}, the era in effect on the year's first day, or

  • {:error, %Calendrical.InvalidDateError{}} for a year the calendar does not have, or

  • {:error, exception}, a Calendrical.MissingFieldsError, for no year.

Examples

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> Calendrical.Hebrew.year_of_era(date.year) ==
...>   Calendrical.Hebrew.year_of_era(date.year, date.month, date.day)
true

year_of_era(year, month, day)

Returns the year of era and era of a date (Calendrical.Era.year_of_era/4).

Arguments

  • year, month and day are a date of this calendar.

Returns

  • {year_of_era, era}, or

  • {:error, %Calendrical.InvalidDateError{}} for a date the calendar does not have, or

  • {:error, exception}, a Calendrical.MissingFieldsError, for no year.

Examples

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> {year_of_era, era} = Calendrical.Hebrew.year_of_era(date.year, date.month, date.day)
iex> year_of_era >= 1 and is_integer(era)
true

iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> {:error, %Calendrical.InvalidDateError{}} = Calendrical.Hebrew.year_of_era(date.year, 99, 1)

years_in_cycle()

Returns the number of years after which this calendar's years repeat, as its info/0 states, or {:error, %Calendrical.NotDefinedError{}}.

Returns

  • The number of years in the cycle, or

  • {:error, %Calendrical.NotDefinedError{}} where the calendar states none.

Examples

# A year has as many days as the year one cycle later
iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Hebrew)
iex> case Calendrical.Hebrew.years_in_cycle() do
...>   {:error, %Calendrical.NotDefinedError{}} -> true
...>   years -> Calendrical.Hebrew.days_in_year(date.year) == Calendrical.Hebrew.days_in_year(date.year + years)
...> end
true