luplo.core.timeparse ==================== .. py:module:: luplo.core.timeparse .. autoapi-nested-parse:: Lightweight time-range parser shared by CLI and MCP idea search. Accepts: - ``""`` (empty) → ``None`` - ISO datetime: ``2026-04-01`` or ``2026-04-01T12:00:00+00:00`` - Relative: ``Nd`` / ``Nw`` (last N days / weeks) - Anchors: ``this_week`` / ``this_month`` / ``this_quarter`` — **since-only**. Anchors return the *start* of the named period, which is the desired semantic for ``--since`` ("everything from then to now") but garbage for ``--until`` ("everything before this period started"). When ``mode='until'`` we reject anchors with a clear error. Naive datetimes get UTC. Garbage input raises ``ValueError`` carrying the list of accepted dialects so callers can surface a friendly message. Functions --------- .. autoapisummary:: luplo.core.timeparse.parse_since Module Contents --------------- .. py:function:: parse_since(value: str | None, *, mode: Literal['since', 'until'] = 'since') -> datetime.datetime | None Parse the time-range dialect; return ``None`` for empty input. ``mode='since'`` (default) accepts every dialect including anchors, which return the start of the named period. ``mode='until'`` rejects anchors because "before the start of this month" almost always filters out the entire current period — likely not what the caller meant. :raises ValueError: when the input is non-empty but not a recognised form, or when ``mode='until'`` and an anchor is supplied. The message names the supported dialects so callers can forward it without further wrapping.