Calendars and conversion¶
hebrewcal ships three calendars, each an immutable dataclass with year, month and
day fields, a to_rd() method and a from_rd() classmethod.
Calendar |
Type |
Module |
|---|---|---|
Gregorian (proleptic) |
|
|
Julian (proleptic) |
|
|
Hebrew |
|
|
All three are re-exported from the package root.
Gregorian¶
The proleptic Gregorian calendar is valid for every year, including years ≤ 0.
>>> from hebrewcal import GregorianDate
>>> GregorianDate(2026, 6, 26).to_rd()
739793
>>> GregorianDate.from_rd(739793)
GregorianDate(year=2026, month=6, day=26)
>>> from hebrewcal.calendars.gregorian import is_leap_year
>>> is_leap_year(2000), is_leap_year(1900), is_leap_year(2024)
(True, False, True)
Dates are validated on construction:
>>> GregorianDate(2026, 2, 30)
Traceback (most recent call last):
...
ValueError: day out of range: 30
Julian¶
The proleptic Julian calendar uses the simple “every fourth year” leap rule. There is no year 0; year −1 precedes year 1.
>>> from hebrewcal import JulianDate
>>> from hebrewcal.calendars.julian import is_leap_year
>>> is_leap_year(1900) # leap in the Julian calendar
True
>>> JulianDate(2026, 6, 13).to_rd()
739793
The Julian/Gregorian reform¶
The 1582 reform skipped from Julian Thursday 4 October 1582 straight to Gregorian
Friday 15 October 1582. hebrewcal never performs this jump silently — it computes
everything through RD and exposes the cutover explicitly:
>>> from hebrewcal import JulianDate, GregorianDate
>>> JulianDate(1582, 10, 4).to_rd()
577735
>>> GregorianDate(1582, 10, 15).to_rd()
577736
>>> # The two are consecutive days: no gap in the RD timeline.
>>> from hebrewcal.calendars.julian import last_gregorian_before_reform
>>> last_gregorian_before_reform()
GregorianDate(year=1582, month=10, day=4)
Regional adoption
The 1582 cutover is the papal one. Many countries adopted the Gregorian calendar much
later (Britain in 1752, Russia in 1918, …). hebrewcal gives you exact RD values for
both calendars; choosing which calendar a historical date was written in is your
decision, not a silent default.
Hebrew¶
The Hebrew date type wires the arithmetic engine (see Hebrew calendar internals) into the calendar contract.
>>> from hebrewcal import HebrewDate, to_gregorian
>>> HebrewDate(5785, 7, 1) # 1 Tishri 5785
HebrewDate(year=5785, month=7, day=1)
>>> to_gregorian(HebrewDate(5785, 7, 1))
GregorianDate(year=2024, month=10, day=3)
Leap years contain a 13th month (Adar II); month 12 becomes Adar I:
>>> HebrewDate(5784, 13, 1).to_rd() > HebrewDate(5784, 12, 1).to_rd()
True
Converting between calendars¶
The high-level helpers all route through RD:
>>> from hebrewcal import GregorianDate, to_hebrew, to_julian
>>> to_hebrew(GregorianDate(1867, 10, 31))
HebrewDate(year=5628, month=8, day=2)
>>> to_julian(GregorianDate(1867, 10, 31))
JulianDate(year=1867, month=10, day=19)
A worked answer to the classic question — “What Hebrew date and weekday corresponds to 31 October 1867?”:
>>> from hebrewcal import GregorianDate, to_hebrew, weekday
>>> g = GregorianDate(1867, 10, 31)
>>> h = to_hebrew(g)
>>> f"{h.day} Marheshvan {h.year}, {weekday(g).name.title()}"
'2 Marheshvan 5628, Thursday'