Calendrical.Islamic.UmmAlQura.Astronomical (Calendrical v0.3.0)

Copy Markdown

Implements the Umm al-Qura calendar for determining the first day of each Hijri month using the astronomical rules documented by R. H. van Gent.

Eras

  • Era 2 (1392–1419 AH / 1972–1999 CE) — Conjunction rule (best effort). The first day of the month is the Gregorian day following the geocentric conjunction. This reproduces 96.7 % of the published KACST dates; the remaining ≈ 3 % differ by one day due to undocumented details in the historical Saudi determination process.

  • Era 3 (1420–1422 AH / 1999–2002 CE) — Moonset-only rule. On the 29th of the current month, if moonset occurs after sunset at Mecca the next day is 1st of the new month; otherwise the month is extended to 30 days.

  • Era 4 (1423 AH onward / 2002 CE onward) — Full Umm al-Qura rule. On the 29th day of the current Hijri month, if both of the following conditions hold as observed from Mecca (21.4225° N, 39.8262° E), then the following day is the 1st day of the new Hijri month:

    1. The geocentric conjunction occurs before sunset in Mecca.
    2. Moonset in Mecca occurs after sunset in Mecca.

    If either condition fails, the current month is extended to 30 days.

Years before 1392 AH are not supported because no reliable astronomical rule has been established for that period.

Accuracy

The astronomical computation uses centre-of-disk sunset and centre-of-disk moonset conventions (matching Skyfield/van Gent) and achieves 99.7 % agreement (934 of 937 months) with the van Gent reference dataset for Era 4 (1423–1500 AH). The three boundary-case months where the algorithm disagrees are:

Hijri monthGregorian (van Gent)Gregorian (algorithm)Root cause
1446/62024-12-022024-12-03Moonset 7 s before sunset
1475/112053-06-172053-06-18Moonset 3 s before sunset (Skyfield also fails)
1485/102063-01-302063-01-31Moonset 5 s before sunset

All three involve moonset-sunset gaps of less than 10 seconds — below the precision floor of any rise/set calculation given atmospheric refraction uncertainty (±2 arcmin ≈ ±10 s). The van Gent reference data — independently corroborated by the hijridate package (dralshehri, sourced from KACST archival publications) — is used as the canonical calendar via Calendrical.Islamic.UmmAlQura.ReferenceData.

Reference

Summary

Functions

Returns a map with the detailed astronomical data used in evaluating the Umm al-Qura rule for the given Gregorian date (which should be the 29th day of the current Hijri month).

Calculates the Gregorian date of the 1st day of the Hijri month identified by hijri_year and hijri_month (1-based, 1 = Muharram … 12 = Dhū al-Ḥijja).

Functions

evaluate_era_4_conditions(date)

@spec evaluate_era_4_conditions(Date.t()) :: {:ok, map()} | {:error, term()}

Returns a map with the detailed astronomical data used in evaluating the Umm al-Qura rule for the given Gregorian date (which should be the 29th day of the current Hijri month).

Returned map keys:

  • :date – the candidate 29th Gregorian date
  • :conjunction_utcDateTime of geocentric conjunction (new moon)
  • :sunset_meccaDateTime of sunset in Mecca (UTC)
  • :moonset_meccaDateTime of moonset in Mecca (UTC), or :no_time
  • :conjunction_before_sunset – boolean
  • :moonset_after_sunset – boolean
  • :new_month_starts_next_day – boolean (true iff both conditions are met)

first_day_of_month(hijri_year, hijri_month)

@spec first_day_of_month(pos_integer(), 1..12) :: {:ok, Date.t()} | {:error, term()}

Calculates the Gregorian date of the 1st day of the Hijri month identified by hijri_year and hijri_month (1-based, 1 = Muharram … 12 = Dhū al-Ḥijja).

  • Era 4 (≥ 1423 AH): full Umm al-Qura rule (conjunction before sunset AND moonset after sunset).
  • Era 3 (1420–1422 AH): moonset-after-sunset only.
  • Era 2 (1392–1419 AH): conjunction within 3 h of 0 h UTC.

Returns {:ok, %Date{}} on success, or {:error, reason} if the year/month falls outside the supported range (< 1392 AH or invalid month).

Examples

iex> Calendrical.Islamic.UmmAlQura.Astronomical.first_day_of_month(1446, 9)
{:ok, ~D[2025-03-01]}   # Era 4 — full rule

iex> Calendrical.Islamic.UmmAlQura.Astronomical.first_day_of_month(1421, 1)
{:ok, ~D[2000-04-06]}   # Era 3 — moonset only

iex> Calendrical.Islamic.UmmAlQura.Astronomical.first_day_of_month(1400, 9)
{:ok, ~D[1980-07-13]}   # Era 2 — conjunction rule