Imports name this capability’s declared dependencies, which fune builds next to it in your project; each one links to its page.
from .dates_add_days import add_days, days_between, parse_iso_date ← from dates.add-days ^1.0.0 · built alongside by fune
from .health_gestational_age_types import GestationalAge
#: Naegele's rule: 280 days (40+0 weeks) from the LMP for a 28-day cycle.
_TERM_DAYS = 280
#: 44+0 weeks: beyond this the dates are almost certainly wrong.
_MAX_DAYS = 308
def gestational_age(lmp_date: str, on_date: str, cycle_length_days: int) -> GestationalAge:
"""Gestational age and estimated due date from the last menstrual period.
A cycle longer or shorter than 28 days moves ovulation, so both are shifted
by the difference, as the NHS due date calculator does.
"""
c = cycle_length_days
if isinstance(c, bool) or not isinstance(c, int) or c < 20 or c > 44:
raise ValueError("cycleLengthDays must be a whole number from 20 to 44, received %r" % (c,))
parse_iso_date(lmp_date)
parse_iso_date(on_date)
shift = c - 28
total_days = days_between(lmp_date, on_date) - shift
if total_days < 0:
raise ValueError("onDate %s is before the adjusted start of pregnancy" % (on_date,))
if total_days > _MAX_DAYS:
raise ValueError("gestational age of %d days is more than 44+0 weeks: check the dates" % (total_days,))
return GestationalAge(
weeks=total_days // 7,
days=total_days % 7,
total_days=total_days,
due_date=add_days(lmp_date, _TERM_DAYS + shift),
)