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 .dates_add_months import add_months ← from dates.add-months ^1.0.0 · built alongside by fune
from .health_age_in_months_types import AgeInMonths
def _month_anniversary(birth_date: str, birth_day: int, months: int) -> str:
"""The day the given number of months is completed. add_months clamps 31
January + 1 month to 28 February; a clamped day has not yet reached the
birth day, so the month completes the day after it (1 March), the same rule
dates.age uses for a 29 February birthday."""
shifted = add_months(birth_date, months)
return add_days(shifted, 1) if parse_iso_date(shifted).day < birth_day else shifted
def age_in_months(birth_date: str, on_date: str) -> AgeInMonths:
"""Completed months and remaining days from ``birth_date`` to ``on_date``."""
birth = parse_iso_date(birth_date)
on = parse_iso_date(on_date)
if on_date < birth_date:
raise ValueError("onDate %s is before birthDate %s" % (on_date, birth_date))
months = (on.year - birth.year) * 12 + (on.month - birth.month)
anniversary = _month_anniversary(birth_date, birth.day, months)
if anniversary > on_date:
months -= 1
anniversary = _month_anniversary(birth_date, birth.day, months)
return AgeInMonths(months=months, days=days_between(anniversary, on_date), total_days=days_between(birth_date, on_date))