from __future__ import annotations from datetime import date as _date from typing import Optional, Union try: from django.utils.dateparse import parse_date as _parse_date except Exception: # pragma: no cover - django not loaded in some tools _parse_date = None # type: ignore DateLike = Union[_date, str, None] def ensure_date(value: DateLike) -> Optional[_date]: """Return a date from a date or ISO string; None stays None. - Accepts datetime.date, 'YYYY-MM-DD' string, or None. - Returns None if parsing fails or value falsy. """ if not value: return None if isinstance(value, _date): return value if isinstance(value, str): if _parse_date is None: return None return _parse_date(value) return None def get_year_from_date(value: DateLike) -> Optional[int]: """Extract year from date or ISO string, else None.""" d = ensure_date(value) return d.year if d else None