Source code for hebrewcal.astro.molad
"""The molad expressed as a civil instant (a mean lunar conjunction).
The molad is the *mean* conjunction used by the Hebrew calendar, reckoned in
**Jerusalem mean time**, where the molad "day" begins at 18:00 the previous
evening. It can differ from the true astronomical new moon by up to ~14 hours;
this module exposes the molad for comparison rather than computing true syzygy.
The returned datetime is **naive** and represents Jerusalem mean time. It is
deliberately not tagged with the modern ``Asia/Jerusalem`` zone, whose standard
time (UTC+2) and daylight saving differ from mean solar time at Jerusalem.
"""
from __future__ import annotations
import datetime
from hebrewcal.calendars.gregorian import GregorianDate
from hebrewcal.hebrew.molad import HALAKIM_PER_DAY, molad_parts
from hebrewcal.hebrew.yeartype import HEBREW_EPOCH
# The synodic month used by the calendar: 29 days, 12 hours, 793 parts.
MOLAD_INTERVAL_PARTS: int = 29 * HALAKIM_PER_DAY + 12 * 1080 + 793
_SECONDS_PER_PART: float = 24 * 3600 / HALAKIM_PER_DAY # 10/3 seconds
[docs]
def molad_breakdown(year: int, month: int) -> tuple[int, int, int]:
"""Return (day_index, hours, parts) of the molad.
``day_index`` is the molad day counted from the Hebrew epoch; ``hours`` and
``parts`` are measured from 18:00 at the start of that day.
"""
day_index, within = divmod(molad_parts(year, month), HALAKIM_PER_DAY)
hours, parts = divmod(within, 1080)
return day_index, hours, parts
[docs]
def molad_moment(year: int, month: int) -> datetime.datetime:
"""Return the molad as a naive datetime in Jerusalem mean time."""
day_index, within = divmod(molad_parts(year, month), HALAKIM_PER_DAY)
g = GregorianDate.from_rd(HEBREW_EPOCH + day_index)
# The Hebrew day begins at 18:00 the previous civil evening; the molad parts
# are counted from there.
start = datetime.datetime(g.year, g.month, g.day) - datetime.timedelta(hours=6)
return start + datetime.timedelta(seconds=within * _SECONDS_PER_PART)