Calendrical. Islamic. UmmAlQura
(Calendrical v2.2.0)
Copy Markdown
Implementation of the Saudi Arabian Umm al-Qura calendar.
The Umm al-Qura (أم القرى, "Mother of Towns" — a name for Mecca) calendar
is the official Hijri calendar of the Kingdom of Saudi Arabia and the
basis for date calculations published by the King Abdulaziz City for
Science and Technology (KACST). It differs from the purely tabular
Hijri calendars (Calendrical.Islamic.Civil and
Calendrical.Islamic.Tbla) in that the start of each month is
determined by an astronomical observation rule applied at Mecca rather
than by a fixed arithmetic cycle. Individual months may therefore
deviate from the tabular value by up to a day.
This module embeds the official month lengths published by KACST,
compiled from priv/umm_al_qura_month_lengths.csv into one bit per
month, and ICU's for the century after them, from
priv/umm_al_qura_icu_month_lengths.csv. Converting an Umm al-Qura date to the Gregorian calendar is an
O(1) lookup, and the reverse a binary search over the years, with no
floating-point arithmetic at runtime.
Coverage
The tables cover 1 AH through 1600 AH (19 July 622 CE through
25 November 2174 CE): KACST's published month lengths for 1 to 1500 AH,
the full range it publishes, and ICU4C's for 1501 to 1600 AH (from
islamcal.cpp, under the Unicode License), which take up from KACST's
without a gap. Run mix calendrical.umm_al_qura.verify --kacst to
compare the tables with KACST's current data.
Years before and after the tables are those of the arithmetic civil
calendar, Calendrical.Islamic.Civil, as ICU falls back to it outside
its own table. Civil 1 Muharram 1 AH and 1601 AH are the days the
tables begin and end on, so no year at either join is lengthened or
shortened. The year before 1 AH is year 0.
From 1300 AH this calendar is ICU's day for day. Before 1300 AH ICU has no table and takes the civil calendar's months, where this one keeps KACST's published months: 8,567 of the 15,588 months of 1 to 1299 AH begin on another day, most of them a day earlier here.
Before 1.4.0 this calendar used R.H. van Gent's tables. Those are an
astronomical reconstruction, reproduced by
Calendrical.Islamic.UmmAlQura.Astronomical, and differ from KACST's
official table in 695 months between 1356 and 1500 AH. The published
rule they apply is KACST's through 1450 AH; from 1451 AH KACST's
projected months begin a third of months a day later, as
Calendrical.Islamic.UmmAlQura.Astronomical explains.
Days begin at midnight by default. date_at/2 maps an absolute instant to
the Hijri date under a chosen day-start convention — midnight, an 18:00
proxy, or true sunset (Maghrib) at Mecca.
Reference
KACST official month lengths, https://umqserv.kacst.gov.sa/api/v1/DateConversion/GetHijriMonthLengths.
R.H. van Gent, "The Umm al-Qura Calendar of Saudi Arabia", https://webspace.science.uu.nl/~gent0113/islam/ummalqura.htm.
Summary
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 Umm al-Qura 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 the Umm al-Qura {year, month, day} for the given ISO day
number, by the civil calendar outside the published tables.
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 Umm al-Qura
year, month, and day, by the civil calendar outside the
published tables.
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 week of a date (Calendrical.Week.day_of_week/5).
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 Hijri year and month.
Months are 29 or 30 days as determined by the published Umm al-Qura
tables, or by the civil calendar outside them.
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 number of whole units between two dates, counted positionally.
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 Gregorian Calendar.date/0 of the first day of the given
Hijri month according to the official Umm al-Qura tables.
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 a year's leap month, or nil where the
year has none.
Returns whether the given Hijri year is a leap year (355 days).
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 last Hijri year covered by the embedded Umm al-Qura tables: KACST's to 1500 AH, then ICU's.
Returns the first Hijri year covered by the embedded Umm al-Qura tables.
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 a
given 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 related Gregorian year of a date
(Calendrical.Era.related_gregorian_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.
Shifts a time by a duration, 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).
Determines if the given Umm al-Qura date is valid.
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 month a CLDR month is written with in a year
(Calendrical.Month.written_month_from_cldr_month/3).
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
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.
Arguments
year,monthanddayare the date's fields in this calendar.hour,minute,secondandmicrosecondare the time of day, returned unchanged.precisionis:year,:quarteror:month.stepis 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.Islamic.UmmAlQura)
iex> {year, month, day, 12, 30, 0, {0, 0}} =
...> Calendrical.Islamic.UmmAlQura.add(date.year, date.month, date.day, 12, 30, 0, {0, 0}, :month, 1)
iex> {year, month, day} == Calendrical.Islamic.UmmAlQura.shift(date.year, date.month, date.day, :months, 1, [])
true
Returns what this calendar's year is built of, :month or :week,
as its info/0 states.
Returns
:weekfor a calendar whose year is built of weeks.:monthotherwise.
Examples
iex> Calendrical.Islamic.UmmAlQura.calendar_base() in [:month, :week]
true
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_typeis 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.Islamic.UmmAlQura.calendar_from_cldr_calendar_type(:gregorian)
{:ok, Calendrical.Gregorian}
iex> {:error, %Localize.UnknownCalendarError{}} =
...> Calendrical.Islamic.UmmAlQura.calendar_from_cldr_calendar_type(:not_a_calendar)
Returns the day a date is written with: the day of its
written_date/3.
Arguments
year,monthanddayare 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.Islamic.UmmAlQura)
iex> {_year, _month, written_day} = Calendrical.Islamic.UmmAlQura.written_date(date.year, date.month, date.day)
iex> Calendrical.Islamic.UmmAlQura.cardinal_day(date.year, date.month, date.day) == written_day
true
Returns the CLDR month a month of the year names without a year
(Calendrical.Month.cldr_month/2).
Arguments
monthis 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.Islamic.UmmAlQura)
iex> Calendrical.Islamic.UmmAlQura.cardinal_month(1) == Calendrical.Islamic.UmmAlQura.cldr_month(date.year, 1)
true
Returns the year a date is written with: the year of its
written_date/3.
Arguments
year,monthanddayare 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.Islamic.UmmAlQura)
iex> {written_year, _month, _day} = Calendrical.Islamic.UmmAlQura.written_date(date.year, date.month, date.day)
iex> Calendrical.Islamic.UmmAlQura.cardinal_year(date.year, date.month, date.day) == written_year
true
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
:gregorianor:hebrew.
Examples
iex> Calendrical.Islamic.UmmAlQura.cldr_calendar_type() == Calendrical.Islamic.UmmAlQura.info().cldr_calendar_type
true
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,monthanddayare a date of this calendar.
Returns
- A CLDR calendar type.
Examples
iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Islamic.UmmAlQura)
iex> in_effect = Calendrical.Info.in_effect(Calendrical.Islamic.UmmAlQura, date.year, date.month, date.day)
iex> Calendrical.Islamic.UmmAlQura.cldr_calendar_type(date.year, date.month, date.day) == in_effect.cldr_calendar_type()
true
Returns the CLDR month of a month of a year
(Calendrical.Month.cldr_month/3).
Arguments
yearandmonthare 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.Islamic.UmmAlQura)
iex> cldr_month = Calendrical.Islamic.UmmAlQura.cldr_month(date.year, date.month)
iex> Calendrical.Islamic.UmmAlQura.written_month_from_cldr_month(date.year, cldr_month) ==
...> Calendrical.Islamic.UmmAlQura.numeric_month(date.year, date.month, date.day)
true
iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Islamic.UmmAlQura)
iex> {:error, %Calendrical.InvalidMonthError{}} = Calendrical.Islamic.UmmAlQura.cldr_month(date.year, 99)
Returns the cyclic year of a date (Calendrical.Era.cyclic_year/4).
Arguments
year,monthanddayare a date of this calendar.
Returns
The date's place in the sexagenary cycle,
1to60, 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}, aCalendrical.MissingFieldsError, for no year.
Examples
iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Islamic.UmmAlQura)
iex> cyclic_year = Calendrical.Islamic.UmmAlQura.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.Islamic.UmmAlQura.cyclic_year(nil, 1, 1)
@spec date_at(DateTime.t(), Keyword.t()) :: {:ok, Date.t()} | {:error, Exception.t()}
Returns the Umm al-Qura date in effect at a given instant, under a chosen day-start convention.
The Islamic day traditionally begins at sunset, so after sunset the
Umm al-Qura date is already the following day. This function maps an
absolute instant to the Hijri date, choosing the day boundary with the
:day_start option. All boundaries are evaluated at Mecca — where the
Umm al-Qura calendar is defined — so the result is the official Hijri date
for that instant regardless of the observer's own time zone.
For the plain civil-day mapping (the calendar's default), convert a date
directly with Date.convert/2 instead.
Arguments
datetimeis aDateTime.t/0— an absolute instant. Its own time zone is used only to fix the instant; the day boundary is always taken at Mecca.
Options
:day_startselects the moment the Umm al-Qura day begins::midnight(the default) — the day begins at 00:00 Mecca time, i.e. the ordinary civil-day mapping.:evening— the day begins at 18:00 Mecca time, the fixed-clock proxy for sunset used by many implementations.:sunset— the day begins at true sunset (Maghrib) at Mecca, computed astronomically viaAstro. This is upper-limb sunset, which differs by a minute or two from the centre-of-disk sunset thatCalendrical.Islamic.UmmAlQura.Astronomicaluses to start each month.
Returns
{:ok, date}— an Umm al-QuraDate.t/0.{:error, %Calendrical.InvalidOptionValueError{}}for an invalid:day_startor:nightfall_angle.{: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 at Mecca: every convention agrees.
iex> Calendrical.Islamic.UmmAlQura.date_at(~U[2025-03-01 06:00:00Z])
{:ok, ~D[1446-09-01 Calendrical.Islamic.UmmAlQura]}
# After sunset the evening convention has rolled to the next Hijri day.
iex> Calendrical.Islamic.UmmAlQura.date_at(~U[2025-03-01 16:00:00Z], day_start: :evening)
{:ok, ~D[1446-09-02 Calendrical.Islamic.UmmAlQura]}
Returns the date of this calendar that written figures name
(date_from_written_date/3), as fields.
Arguments
year,monthanddayare the figures a date is written with, aswritten_date/3returns 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.Islamic.UmmAlQura)
iex> {year, month, day} = Calendrical.Islamic.UmmAlQura.written_date(date.year, date.month, date.day)
iex> Calendrical.Islamic.UmmAlQura.date_from_cardinal_date(year, month, day) == {date.year, date.month, date.day}
true
iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Islamic.UmmAlQura)
iex> {:error, %Calendrical.InvalidDateError{}} = Calendrical.Islamic.UmmAlQura.date_from_cardinal_date(date.year, 0, 1)
Returns the date of a day of a year, counted from the year's first day.
Arguments
yearis a year of this calendar.day_of_yearis the day of the year, counted from 1.
Returns
A
Date.t/0of 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.Islamic.UmmAlQura)
iex> day_of_year = Calendrical.Islamic.UmmAlQura.day_of_year(date.year, date.month, date.day)
iex> Calendrical.Islamic.UmmAlQura.date_from_day_of_year(date.year, day_of_year) == date
true
iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Islamic.UmmAlQura)
iex> {:error, %Calendrical.InvalidDateError{}} = Calendrical.Islamic.UmmAlQura.date_from_day_of_year(date.year, 1000)
Returns the Umm al-Qura {year, month, day} for the given ISO day
number, by the civil calendar outside the published tables.
Arguments
iso_daysis the number of days since the ISO epoch.
Returns
- A
{year, month, day}tuple.
Examples
iex> iso_days = Date.to_gregorian_days(~D[2025-03-01])
iex> Calendrical.Islamic.UmmAlQura.date_from_iso_days(iso_days)
{1446, 9, 1}
Returns the date of a day of a week of a week-year
(Calendrical.Week.date_from_week_date/4).
Arguments
week_yearis a week-year of this calendar.weekis a week of the week-year.dayis the day of the week, numbered from 1 for the day the calendar's weeks begin on.
Returns
A
Date.t/0of this calendar, or{:error, %Calendrical.InvalidDateError{}}where the week has no such day.
Examples
iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Islamic.UmmAlQura)
iex> {week_year, week, day} = Calendrical.Islamic.UmmAlQura.week_date_from_date(date.year, date.month, date.day)
iex> Calendrical.Islamic.UmmAlQura.date_from_week_date(week_year, week, day) == date
true
iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Islamic.UmmAlQura)
iex> {:error, %Calendrical.InvalidDateError{}} = Calendrical.Islamic.UmmAlQura.date_from_week_date(date.year, 1, 8)
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,monthanddayare the figures a date is written with, aswritten_date/3returns 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.Islamic.UmmAlQura)
iex> {year, month, day} = Calendrical.Islamic.UmmAlQura.written_date(date.year, date.month, date.day)
iex> Calendrical.Islamic.UmmAlQura.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.Islamic.UmmAlQura)
iex> Calendrical.Islamic.UmmAlQura.date_from_written_date(date.year, 0, 1)
{:error, :invalid_date}
Returns the number of ISO days for the given Umm al-Qura
year, month, and day, by the civil calendar outside the
published tables.
Arguments
yearis the Hijri year.monthis the Hijri month.dayis the day of the month.
Returns
- The number of days since the ISO epoch, as an integer.
Examples
iex> Calendrical.Islamic.UmmAlQura.date_to_iso_days(1446, 9, 1) ==
...> Date.to_gregorian_days(~D[2025-03-01])
true
Returns the dates of this calendar, earliest first, whose month and day are those given and that fall in a Gregorian year.
Arguments
gregorian_yearis the Gregorian year to search within.monthanddayare a month and a day of this calendar.
Returns
- A list of zero, one or two
Date.t/0of 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.Islamic.UmmAlQura)
iex> date in Calendrical.Islamic.UmmAlQura.dates_in_gregorian_year(2024, date.month, date.day)
true
Returns the days a month of a year has, as runs of their numbers
(Calendrical.Month.day_numbers/3).
Arguments
yearandmonthare 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.Islamic.UmmAlQura)
iex> Calendrical.Islamic.UmmAlQura.day_numbers(date.year, date.month) ==
...> [1..Calendrical.Islamic.UmmAlQura.days_in_month(date.year, date.month)//1]
true
iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Islamic.UmmAlQura)
iex> Calendrical.Islamic.UmmAlQura.day_numbers(date.year, 99)
[]
Returns the day of era and era of a date (Calendrical.Era.day_of_era/4).
Arguments
year,monthanddayare 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}, aCalendrical.MissingFieldsError, for a missing field.
Examples
iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Islamic.UmmAlQura)
iex> {day_of_era, era} = Calendrical.Islamic.UmmAlQura.day_of_era(date.year, date.month, date.day)
iex> {_year_of_era, year_era} = Calendrical.Islamic.UmmAlQura.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.Islamic.UmmAlQura)
iex> {:error, %Calendrical.InvalidDateError{}} = Calendrical.Islamic.UmmAlQura.day_of_era(date.year, date.month, 0)
Returns the day of the week of a date (Calendrical.Week.day_of_week/5).
Arguments
year,monthanddayare a date of this calendar.starting_onis:defaultfor the day this calendar's weeks begin on, or the name of a weekday,:mondayto: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}, aCalendrical.MissingFieldsError, for a missing field.
Examples
# 1 June 2024 is a Saturday
iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Islamic.UmmAlQura)
iex> Calendrical.Islamic.UmmAlQura.day_of_week(date.year, date.month, date.day, :monday)
{6, 1, 7}
iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Islamic.UmmAlQura)
iex> {:error, %Calendrical.InvalidDateError{}} = Calendrical.Islamic.UmmAlQura.day_of_week(date.year, date.month, 0, :monday)
Returns the day of the year of a date (Calendrical.Period.day_of_year/4).
Arguments
year,monthanddayare 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}, aCalendrical.MissingFieldsError, for a missing field.
Examples
iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Islamic.UmmAlQura)
iex> first_day = Calendrical.Islamic.UmmAlQura.year(date.year).first
iex> Calendrical.Islamic.UmmAlQura.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.Islamic.UmmAlQura)
iex> {:error, %Calendrical.InvalidDateError{}} = Calendrical.Islamic.UmmAlQura.day_of_year(date.year, date.month, 0)
Returns the number of days in a month without a year
(Calendrical.Month.days_in_month/2).
Arguments
monthis 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}, aCalendrical.MissingFieldsError, where the month isnil.
Examples
iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Islamic.UmmAlQura)
iex> {fewest, most} = Calendrical.Islamic.UmmAlQura.days_in_month_bounds(date.month)
iex> case Calendrical.Islamic.UmmAlQura.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.Islamic.UmmAlQura.days_in_month(99)
@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 Hijri year and month.
Months are 29 or 30 days as determined by the published Umm al-Qura
tables, or by the civil calendar outside them.
Arguments
yearis the Hijri year.monthis the Hijri month, from1to12.
Returns
The number of days in the month,
29or30, or{:error, %Calendrical.InvalidMonthError{}}for a month the year does not have, or{:error, %Calendrical.MissingFieldsError{}}where the year or the month isnil.
Examples
iex> Calendrical.Islamic.UmmAlQura.days_in_month(1446, 9)
29
Returns the fewest and the most days a month has in any year
(Calendrical.Month.days_in_month_bounds/2).
Arguments
monthis 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.Islamic.UmmAlQura)
iex> {fewest, most} = Calendrical.Islamic.UmmAlQura.days_in_month_bounds(date.month)
iex> Calendrical.Islamic.UmmAlQura.days_in_month(date.year, date.month) in fewest..most
true
iex> {:error, %Calendrical.InvalidMonthError{}} = Calendrical.Islamic.UmmAlQura.days_in_month_bounds(99)
Returns the number of days in a week.
Returns
7.
Examples
iex> Calendrical.Islamic.UmmAlQura.days_in_week()
7
Returns the number of days in a year (Calendrical.Period.days_in_year/2).
Arguments
yearis 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}, aCalendrical.MissingFieldsError, for no year.
Examples
iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Islamic.UmmAlQura)
iex> Calendrical.Islamic.UmmAlQura.days_in_year(date.year) == Enum.count(Calendrical.Islamic.UmmAlQura.year(date.year))
true
iex> {:error, %Calendrical.MissingFieldsError{}} = Calendrical.Islamic.UmmAlQura.days_in_year(nil)
Returns the number of whole units between two dates, counted positionally.
Arguments
fromandtoare dates of this calendar as{year, month, day}tuples.date_partis one of:years,:quarters,:months,:weeksor:days.
Returns
The largest number of
date_parts that can be added tofromwithout passingto, negative wheretois beforefrom, or{:error, %Calendrical.InvalidDateError{}}for afromortothe calendar does not have,{:error, %Calendrical.MissingFieldsError{}}for one missing a field, or{:error, %Calendrical.InvalidPartError{}}for adate_partother than the five.
Examples
iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Islamic.UmmAlQura)
iex> from = {date.year, date.month, date.day}
iex> Calendrical.Islamic.UmmAlQura.diff(from, {date.year + 1, date.month, date.day}, :years)
1
iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Islamic.UmmAlQura)
iex> later = Date.add(date, 10)
iex> Calendrical.Islamic.UmmAlQura.diff({later.year, later.month, later.day}, {date.year, date.month, date.day}, :days)
-10
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.Islamic.UmmAlQura.epoch() |> is_integer()
true
Returns the CLDR calendar type that names this calendar's eras, as
its info/0 states.
Returns
- A CLDR calendar type such as
:gregorianor:japanese.
Examples
iex> Calendrical.Islamic.UmmAlQura.era_calendar_type() == Calendrical.Islamic.UmmAlQura.info().era_calendar_type
true
Returns the extended year of a date (Calendrical.Era.extended_year/4).
Arguments
year,monthanddayare 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}, aCalendrical.MissingFieldsError, for no year.
Examples
iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Islamic.UmmAlQura)
iex> Calendrical.Islamic.UmmAlQura.extended_year(date.year, date.month, date.day) == date.year
true
iex> {:error, %Calendrical.MissingFieldsError{}} = Calendrical.Islamic.UmmAlQura.extended_year(nil, 1, 1)
@spec first_day_of_month(year(), month()) :: {:ok, Date.t()} | {:error, Exception.t()}
Returns the Gregorian Calendar.date/0 of the first day of the given
Hijri month according to the official Umm al-Qura tables.
Arguments
hijri_yearis the Hijri year.hijri_monthis the Hijri month, from1to12.
Returns
{:ok, date}wheredateis the GregorianDate.t/0of the first day of the month.{:error, %Calendrical.IslamicYearOutOfRangeError{}}if the requested month falls outside the embedded data range, where the calendar's months are the civil calendar's.{:error, %Calendrical.InvalidMonthError{}}for a month that is not1to12.
Examples
iex> Calendrical.Islamic.UmmAlQura.first_day_of_month(1446, 9)
{:ok, ~D[2025-03-01]}
iex> {:error, %Calendrical.IslamicYearOutOfRangeError{}} =
...> Calendrical.Islamic.UmmAlQura.first_day_of_month(1700, 1)
iex> {:error, %Calendrical.InvalidMonthError{year: 1446, month: 13}} =
...> Calendrical.Islamic.UmmAlQura.first_day_of_month(1446, 13)
Returns the static facts about this calendar, as
Calendrical.Info.t/0.
Returns
- A
Calendrical.Info.t/0describing this calendar.
Examples
iex> Calendrical.Islamic.UmmAlQura.info().calendar
Calendrical.Islamic.UmmAlQura
Returns the ISO 8601 week-year and week of the day a date names
(Calendrical.Week.iso_week_of_year/4).
Arguments
year,monthanddayare 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.Islamic.UmmAlQura)
iex> Calendrical.Islamic.UmmAlQura.iso_week_of_year(date.year, date.month, date.day)
{2024, 22}
Returns the position of a year's leap month, or nil where the
year has none.
Arguments
yearis a year of this calendar.
Returns
The leap month's position in the year, or
nilwhere the year has no leap month, as for anything but an integer year.
Examples
iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Islamic.UmmAlQura)
iex> leap_month = Calendrical.Islamic.UmmAlQura.leap_month(date.year)
iex> is_nil(leap_month) or leap_month in 1..Calendrical.Islamic.UmmAlQura.months_in_year(date.year)
true
Returns whether the given Hijri year is a leap year (355 days).
Arguments
yearis the Hijri year.
Returns
trueif the year has 355 days, otherwisefalse.
Examples
iex> Calendrical.Islamic.UmmAlQura.leap_year?(1447)
true
iex> Calendrical.Islamic.UmmAlQura.leap_year?(1446)
false
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
yearandmonthare 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.Islamic.UmmAlQura)
iex> Calendrical.Islamic.UmmAlQura.lunar_month_of_year(date.year, date.month) ==
...> Calendrical.Islamic.UmmAlQura.traditional_month(date.year, date.month)
true
iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Islamic.UmmAlQura)
iex> {:error, %Calendrical.InvalidMonthError{}} = Calendrical.Islamic.UmmAlQura.lunar_month_of_year(date.year, 99)
@spec max_year() :: 1600
Returns the last Hijri year covered by the embedded Umm al-Qura tables: KACST's to 1500 AH, then ICU's.
Returns
- The last Hijri year of the tables, as an integer.
Examples
iex> Calendrical.Islamic.UmmAlQura.max_year()
1600
@spec min_year() :: 1
Returns the first Hijri year covered by the embedded Umm al-Qura tables.
Returns
- The first Hijri year of the tables, as an integer.
Examples
iex> Calendrical.Islamic.UmmAlQura.min_year()
1
Returns the days of a month of a year (Calendrical.Period.month/3).
Arguments
yearandmonthare a month of this calendar.
Returns
A
Date.Range.t/0, or{:error, %Calendrical.InvalidDateError{}}for a month the year does not have, or{:error, exception}, aCalendrical.MissingFieldsError, for a missing year or month.
Examples
iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Islamic.UmmAlQura)
iex> date in Calendrical.Islamic.UmmAlQura.month(date.year, date.month)
true
iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Islamic.UmmAlQura)
iex> {:error, %Calendrical.InvalidDateError{}} = Calendrical.Islamic.UmmAlQura.month(date.year, 99)
Returns the position of a traditional month in a year
(Calendrical.Month.month_from_traditional/3).
Arguments
yearis a year of this calendar.traditional_monthis 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.Islamic.UmmAlQura)
iex> traditional_month = Calendrical.Islamic.UmmAlQura.traditional_month(date.year, date.month)
iex> Calendrical.Islamic.UmmAlQura.month_from_traditional(date.year, traditional_month) == date.month
true
iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Islamic.UmmAlQura)
iex> {:error, %Calendrical.InvalidMonthError{}} = Calendrical.Islamic.UmmAlQura.month_from_traditional(date.year, 99)
Returns the months a year has, as runs of their numbers
(Calendrical.Month.month_numbers/2).
Arguments
yearis 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.Islamic.UmmAlQura)
iex> Calendrical.Islamic.UmmAlQura.month_numbers(date.year) == [1..Calendrical.Islamic.UmmAlQura.months_in_year(date.year)//1]
true
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,monthanddayare a date of this calendar. The year and the day may benil: 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 aCalendrical.MissingFieldsErrorwhere the month isnil.
Examples
iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Islamic.UmmAlQura)
iex> Calendrical.Islamic.UmmAlQura.month_of_year(date.year, date.month, date.day) == Calendrical.Islamic.UmmAlQura.cldr_month(date.year, date.month)
true
iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Islamic.UmmAlQura)
iex> {:error, %Calendrical.InvalidDateError{}} = Calendrical.Islamic.UmmAlQura.month_of_year(date.year, date.month, 0)
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.Islamic.UmmAlQura.months_in_leap_year() >= Calendrical.Islamic.UmmAlQura.months_in_ordinary_year()
true
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.Islamic.UmmAlQura.months_in_ordinary_year() <= Calendrical.Islamic.UmmAlQura.months_in_leap_year()
true
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 boundsmonths_in_year_bounds/0gives.
Examples
iex> case Calendrical.Islamic.UmmAlQura.months_in_year() do
...> months when is_integer(months) -> months == Calendrical.Islamic.UmmAlQura.months_in_leap_year()
...> {:ambiguous, fewest..most//1} -> {fewest, most} == Calendrical.Islamic.UmmAlQura.info().months_in_year
...> {:error, %Calendrical.NotDefinedError{}} -> is_list(Calendrical.Islamic.UmmAlQura.info().members)
...> end
true
Returns the number of months in a
given year.
Arguments
yearis the year in this calendar.
Returns
The number of months in the year, as a positive integer, or
{:error, %Calendrical.MissingFieldsError{}}whereyearisnil, or{:error, %Calendrical.InvalidDateError{}}whereyearis no integer.
Examples
iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Islamic.UmmAlQura)
iex> Calendrical.Islamic.UmmAlQura.months_in_year(date.year) >= date.month
true
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.Islamic.UmmAlQura.months_in_year_bounds()
iex> fewest <= Calendrical.Islamic.UmmAlQura.months_in_ordinary_year() and
...> most >= Calendrical.Islamic.UmmAlQura.months_in_leap_year()
true
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_daysis{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.Islamic.UmmAlQura)
iex> {year, month, day, 12, 0, 0, {0, 6}} =
...> Calendrical.Islamic.UmmAlQura.naive_datetime_from_iso_days({739403, {43200000000, 86400000000}})
iex> {year, month, day} == {date.year, date.month, date.day}
true
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,monthanddayare a date of this calendar.hour,minute,secondandmicrosecondare 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.Islamic.UmmAlQura)
iex> Calendrical.Islamic.UmmAlQura.naive_datetime_to_iso_days(date.year, date.month, date.day, 12, 0, 0, {0, 6})
{739403, {43200000000, 86400000000}}
Returns the days of a named month in a year
(Calendrical.Month.named_month/3).
Arguments
yearis a year of this calendar.named_monthis 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.Islamic.UmmAlQura)
iex> cldr_month = Calendrical.Islamic.UmmAlQura.cldr_month(date.year, date.month)
iex> Calendrical.Islamic.UmmAlQura.named_month(date.year, cldr_month) |> Enum.any?(&(date in &1))
true
iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Islamic.UmmAlQura)
iex> Calendrical.Islamic.UmmAlQura.named_month(date.year, 99)
[]
Returns the number a date's month is written with in figures: the
month of its written_date/3.
Arguments
year,monthanddayare 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.Islamic.UmmAlQura)
iex> {_year, written_month, _day} = Calendrical.Islamic.UmmAlQura.written_date(date.year, date.month, date.day)
iex> Calendrical.Islamic.UmmAlQura.numeric_month(date.year, date.month, date.day) == written_month
true
Returns the position in a year of a traditional month
(Calendrical.Month.month_from_traditional/3), as {:ok, month}.
Arguments
yearis a year of this calendar.traditional_monthis 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.Islamic.UmmAlQura)
iex> traditional_month = Calendrical.Islamic.UmmAlQura.traditional_month(date.year, date.month)
iex> Calendrical.Islamic.UmmAlQura.ordinal_month_from_traditional(date.year, traditional_month) == {:ok, date.month}
true
iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Islamic.UmmAlQura)
iex> {:error, %Calendrical.InvalidMonthError{}} = Calendrical.Islamic.UmmAlQura.ordinal_month_from_traditional(date.year, 99)
Parses a date written in this calendar's own notation.
Arguments
stringis a date writtenYYYY-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.Islamic.UmmAlQura)
iex> Calendrical.Islamic.UmmAlQura.parse_date(Date.to_string(date)) == {:ok, {date.year, date.month, date.day}}
true
iex> Calendrical.Islamic.UmmAlQura.parse_date("not a date")
{:error, :invalid_format}
Parses a naive datetime written in this calendar's own notation.
Arguments
stringis a date asparse_date/1reads it, thenTor a space and a time of day.
Returns
{:ok, {year, month, day, hour, minute, second, microsecond}}, or{:error, reason}, such as:invalid_formator: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.Islamic.UmmAlQura)
iex> Calendrical.Islamic.UmmAlQura.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.Islamic.UmmAlQura.parse_naive_datetime("2024-06-01")
{:error, :invalid_format}
Parses a UTC datetime written in this calendar's own notation.
Arguments
stringis a date asparse_date/1reads it, thenTor a space, a time of day and an offset from UTC,Zor±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_dateor: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.Islamic.UmmAlQura)
iex> Calendrical.Islamic.UmmAlQura.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.Islamic.UmmAlQura)
iex> Calendrical.Islamic.UmmAlQura.parse_utc_datetime(Date.to_string(date) <> "T12:00:00")
{:error, :missing_offset}
Returns the calendar a date written for this calendar is parsed in,
as its info/0 states.
Returns
- A calendar module.
Examples
iex> Calendrical.Islamic.UmmAlQura.parsing_calendar() == Calendrical.Islamic.UmmAlQura.info().parsing_calendar
true
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.Islamic.UmmAlQura)
iex> in_effect = Calendrical.Info.in_effect(Calendrical.Islamic.UmmAlQura, date.year, date.month, date.day)
iex> in_effect in Calendrical.Islamic.UmmAlQura.parsing_calendars()
true
Returns the number of periods in a year: its months.
Arguments
yearis a year of this calendar.
Returns
- The number of months in the year, as
months_in_year/1returns it.
Examples
iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Islamic.UmmAlQura)
iex> Calendrical.Islamic.UmmAlQura.periods_in_year(date.year) == Calendrical.Islamic.UmmAlQura.months_in_year(date.year)
true
Returns the days of a quadrimester of a year
(Calendrical.Period.quadrimester/3).
Arguments
yearis a year of this calendar.quadrimesteris the quadrimester,1to3.
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 isnil.
Examples
iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Islamic.UmmAlQura)
iex> Calendrical.Islamic.UmmAlQura.quadrimester(date.year, 1).first == Calendrical.Islamic.UmmAlQura.year(date.year).first
true
iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Islamic.UmmAlQura)
iex> {:error, %Calendrical.InvalidDateError{}} = Calendrical.Islamic.UmmAlQura.quadrimester(date.year, 4)
Returns the days of a quarter of a year (Calendrical.Period.quarter/3).
Arguments
yearis a year of this calendar.quarteris the quarter,1to4.
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 isnil.
Examples
iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Islamic.UmmAlQura)
iex> quarter = Calendrical.Islamic.UmmAlQura.quarter_of_year(date.year, date.month, date.day)
iex> date in Calendrical.Islamic.UmmAlQura.quarter(date.year, quarter)
true
iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Islamic.UmmAlQura)
iex> {:error, %Calendrical.InvalidDateError{}} = Calendrical.Islamic.UmmAlQura.quarter(date.year, 5)
Returns the quarter of the year a date falls in
(Calendrical.Period.quarter_of_year/4).
Arguments
year,monthanddayare a date of this calendar.
Returns
The quarter,
1to4, or{:error, %Calendrical.InvalidDateError{}}for a date the calendar does not have, or{:error, exception}, aCalendrical.MissingFieldsError, for a missing year or month.
Examples
iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Islamic.UmmAlQura)
iex> Calendrical.Islamic.UmmAlQura.quarter_of_year(date.year, date.month, date.day) in 1..4
true
iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Islamic.UmmAlQura)
iex> {:error, %Calendrical.InvalidDateError{}} = Calendrical.Islamic.UmmAlQura.quarter_of_year(date.year, date.month, 0)
Returns the days of a semester of a year (Calendrical.Period.semester/3).
Arguments
yearis a year of this calendar.semesteris the semester,1or2.
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 isnil.
Examples
iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Islamic.UmmAlQura)
iex> Calendrical.Islamic.UmmAlQura.semester(date.year, 1).first == Calendrical.Islamic.UmmAlQura.year(date.year).first
true
iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Islamic.UmmAlQura)
iex> {:error, %Calendrical.InvalidDateError{}} = Calendrical.Islamic.UmmAlQura.semester(date.year, 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).
Arguments
year,monthanddayare a date of this calendar.date_partis one of:years,:quarters,:months,:weeksor:days.incrementis the number of units, which may be negative.optionsis a keyword list of options.
Options
:clampis whether a day the resulting month lacks becomes its last day. The default istrue.
Returns
{year, month, day}of this calendar, or{:error, %Calendrical.InvalidDateError{}}whereyear,monthanddayare no date of this calendar, or{:error, %Calendrical.MissingFieldsError{}}where a field isnil.
Examples
iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Islamic.UmmAlQura)
iex> Calendrical.Islamic.UmmAlQura.shift(date.year, date.month, date.day, :days, 0)
{date.year, date.month, date.day}
Shifts a date by a duration: its years and months together, as
shift/6 adds months, and then its weeks and days.
Arguments
year,monthanddayare a date of this calendar.durationis aDuration.t/0.
Returns
{year, month, day}of this calendar.
Examples
iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Islamic.UmmAlQura)
iex> {year, month, day} = Calendrical.Islamic.UmmAlQura.shift_date(date.year, date.month, date.day, Duration.new!(day: 7))
iex> Date.new!(year, month, day, Calendrical.Islamic.UmmAlQura) == Date.add(date, 7)
true
Shifts a naive datetime by a duration: its date as shift_date/4
shifts it, and its time as Calendar.ISO does.
Arguments
year,monthanddayare a date of this calendar.hour,minute,secondandmicrosecondare a time of day, the microsecond as{microseconds, precision}.durationis aDuration.t/0.
Returns
{year, month, day, hour, minute, second, microsecond}of this calendar.
Examples
iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Islamic.UmmAlQura)
iex> next_day = Date.add(date, 1)
iex> Calendrical.Islamic.UmmAlQura.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
Shifts a time by a duration, as Calendar.ISO does.
Arguments
hour,minute,secondandmicrosecondare a time of day, the microsecond as{microseconds, precision}.durationis aDuration.t/0of time units.
Returns
{hour, minute, second, microsecond}, wrapped around midnight.
Examples
iex> Calendrical.Islamic.UmmAlQura.shift_time(23, 0, 0, {0, 0}, Duration.new!(hour: 2))
{1, 0, 0, {0, 0}}
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
indexis the solar term's number,1(lichun, 315° of solar longitude) to24, every 15° on.gregorian_yearis a Gregorian year.
Returns
{:ok, date}, aDate.t/0inCalendrical.Gregorian, or{:error, %Calendrical.InvalidSolarTermError{}}whereindexis not1to24.
Examples
# Qingming, the fifth solar term
iex> Calendrical.Islamic.UmmAlQura.solar_term(5, 2025)
{:ok, ~D[2025-04-04 Calendrical.Gregorian]}
iex> Calendrical.Islamic.UmmAlQura.solar_term(25, 2025)
{:error, %Calendrical.InvalidSolarTermError{index: 25}}
Returns the traditional number of the month a year's leap month
follows, or nil (Calendrical.Month.traditional_leap_month/2).
Arguments
yearis a year of this calendar.
Returns
The traditional number of the month the leap month follows, or
nilwhere the year has no leap month.
Examples
iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Islamic.UmmAlQura)
iex> is_nil(Calendrical.Islamic.UmmAlQura.traditional_leap_month(date.year)) ==
...> is_nil(Calendrical.Islamic.UmmAlQura.leap_month(date.year))
true
Returns a month of a year as this calendar names it
(Calendrical.Month.traditional_month/3).
Arguments
yearandmonthare 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.Islamic.UmmAlQura)
iex> Calendrical.Islamic.UmmAlQura.traditional_month(date.year, date.month) ==
...> Enum.at(Calendrical.Islamic.UmmAlQura.traditional_months(date.year), date.month - 1)
true
iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Islamic.UmmAlQura)
iex> {:error, %Calendrical.InvalidMonthError{}} = Calendrical.Islamic.UmmAlQura.traditional_month(date.year, 99)
Returns a year's months in order, named traditionally
(Calendrical.Month.traditional_months/2).
Arguments
yearis 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.Islamic.UmmAlQura)
iex> length(Calendrical.Islamic.UmmAlQura.traditional_months(date.year)) ==
...> Calendrical.Islamic.UmmAlQura.months_in_year(date.year)
true
Determines if the given Umm al-Qura date is valid.
A date is valid if its month is in 1..12 and its day is between
1 and the number of days in that month: by the published tables for
1 AH to 1500 AH, and by the civil calendar for other years.
Arguments
yearis the Hijri year.monthis the Hijri month.dayis the day of the month.
Returns
trueif the date is valid, otherwisefalse.
Examples
iex> Calendrical.Islamic.UmmAlQura.valid_date?(1446, 9, 1)
true
iex> Calendrical.Islamic.UmmAlQura.valid_date?(1446, 13, 1)
false
Returns the seven days of a week of a year (Calendrical.Week.week/3).
Arguments
yearis a year of this calendar.weekis a week of the year.
Returns
A
Date.Range.t/0of 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 isnil.
Examples
iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Islamic.UmmAlQura)
iex> {week_year, week} = Calendrical.Islamic.UmmAlQura.week_of_year(date.year, date.month, date.day)
iex> days = Calendrical.Islamic.UmmAlQura.week(week_year, week)
iex> {Enum.count(days), date in days}
{7, true}
iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Islamic.UmmAlQura)
iex> {:error, %Calendrical.InvalidDateError{}} = Calendrical.Islamic.UmmAlQura.week(date.year, 0)
Returns the week-year, the week and the day of the week of a date
(Calendrical.Week.week_date_from_date/4).
Arguments
year,monthanddayare 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.Islamic.UmmAlQura)
iex> {week_year, week, day} = Calendrical.Islamic.UmmAlQura.week_date_from_date(date.year, date.month, date.day)
iex> {week_year, week} == Calendrical.Islamic.UmmAlQura.week_of_year(date.year, date.month, date.day) and day in 1..7
true
Returns the month and the week of the month a date is in
(Calendrical.Week.week_of_month/4).
Arguments
year,monthanddayare 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.Islamic.UmmAlQura)
iex> {month, week} = Calendrical.Islamic.UmmAlQura.week_of_month(date.year, date.month, date.day)
iex> month in (date.month - 1)..(date.month + 1) and week >= 1
true
Returns the week-year and the week of the year a date is in
(Calendrical.Week.week_of_year/4).
Arguments
year,monthanddayare 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: aCalendrical.MissingFieldsErrorfor a date missing a field, and aCalendrical.InvalidDateErrorotherwise.
Examples
iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Islamic.UmmAlQura)
iex> {week_year, week} = Calendrical.Islamic.UmmAlQura.week_of_year(date.year, date.month, date.day)
iex> date in Calendrical.Islamic.UmmAlQura.week(week_year, week)
true
iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Islamic.UmmAlQura)
iex> {:error, %Calendrical.InvalidDateError{}} = Calendrical.Islamic.UmmAlQura.week_of_year(date.year, date.month, 0)
Returns the number of weeks in a week-year
(Calendrical.Week.weeks_in_week_year/2).
Arguments
week_yearis 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.Islamic.UmmAlQura)
iex> {week_year, week, _day} = Calendrical.Islamic.UmmAlQura.week_date_from_date(date.year, date.month, date.day)
iex> week <= Calendrical.Islamic.UmmAlQura.weeks_in_week_year(week_year)
true
Returns the number of weeks in a year (Calendrical.Week.weeks_in_year/2).
Arguments
yearis 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.Islamic.UmmAlQura)
iex> {week_year, week} = Calendrical.Islamic.UmmAlQura.week_of_year(date.year, date.month, date.day)
iex> week <= Calendrical.Islamic.UmmAlQura.weeks_in_year(week_year)
true
Returns the weeks of a month of a year in order
(Calendrical.Week.weeks_of_month/3).
Arguments
yearandmonthare a month of this calendar.
Returns
A list of
Date.Range.t/0, one for each weekweek_of_month/3names 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.Islamic.UmmAlQura)
iex> Calendrical.Islamic.UmmAlQura.weeks_of_month(date.year, date.month) |> Enum.all?(&(Enum.count(&1) == 7))
true
iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Islamic.UmmAlQura)
iex> {:error, %Calendrical.InvalidMonthError{}} = Calendrical.Islamic.UmmAlQura.weeks_of_month(date.year, 99)
Returns the figures a date is written with: its own fields, in a calendar whose dates are written as its own.
Arguments
year,monthanddayare 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.Islamic.UmmAlQura)
iex> {year, month, day} = Calendrical.Islamic.UmmAlQura.written_date(date.year, date.month, date.day)
iex> Calendrical.Islamic.UmmAlQura.date_from_written_date(year, month, day) == {:ok, {date.year, date.month, date.day}}
true
Returns the month a CLDR month is written with in a year
(Calendrical.Month.written_month_from_cldr_month/3).
Arguments
yearis a year of this calendar.cldr_monthis a CLDR month number, or{month, :leap}.
Returns
The month as
written_date/3writes it, or{:error, :invalid_month}where the year has no month of that name. The reason is an atom, not an exception: Localize's date parser reads it, whereCalendrical.Month.written_month_from_cldr_month/3answers with an exception.
Examples
iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Islamic.UmmAlQura)
iex> {_year, written_month, _day} = Calendrical.Islamic.UmmAlQura.written_date(date.year, date.month, date.day)
iex> cldr_month = Calendrical.Islamic.UmmAlQura.cldr_month(date.year, date.month)
iex> Calendrical.Islamic.UmmAlQura.written_month_from_cldr_month(date.year, cldr_month) == written_month
true
iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Islamic.UmmAlQura)
iex> Calendrical.Islamic.UmmAlQura.written_month_from_cldr_month(date.year, 99)
{:error, :invalid_month}
Returns the days of a year (Calendrical.Period.year/2).
Arguments
yearis a year of this calendar.
Returns
A
Date.Range.t/0, or{:error, %Calendrical.InvalidDateError{}}for a year the calendar does not have, or{:error, exception}, aCalendrical.MissingFieldsError, for no year.
Examples
iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Islamic.UmmAlQura)
iex> date in Calendrical.Islamic.UmmAlQura.year(date.year)
true
iex> {:error, %Calendrical.MissingFieldsError{}} = Calendrical.Islamic.UmmAlQura.year(nil)
Returns the year of era and era of a year (Calendrical.Era.year_of_era/2).
Arguments
yearis 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}, aCalendrical.MissingFieldsError, for no year.
Examples
iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Islamic.UmmAlQura)
iex> Calendrical.Islamic.UmmAlQura.year_of_era(date.year) ==
...> Calendrical.Islamic.UmmAlQura.year_of_era(date.year, date.month, date.day)
true
Returns the year of era and era of a date (Calendrical.Era.year_of_era/4).
Arguments
year,monthanddayare 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}, aCalendrical.MissingFieldsError, for no year.
Examples
iex> {:ok, date} = Date.convert(~D[2024-06-01], Calendrical.Islamic.UmmAlQura)
iex> {year_of_era, era} = Calendrical.Islamic.UmmAlQura.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.Islamic.UmmAlQura)
iex> {:error, %Calendrical.InvalidDateError{}} = Calendrical.Islamic.UmmAlQura.year_of_era(date.year, 99, 1)
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.Islamic.UmmAlQura)
iex> case Calendrical.Islamic.UmmAlQura.years_in_cycle() do
...> {:error, %Calendrical.NotDefinedError{}} -> true
...> years -> Calendrical.Islamic.UmmAlQura.days_in_year(date.year) == Calendrical.Islamic.UmmAlQura.days_in_year(date.year + years)
...> end
true