Cycle-aware date arithmetic for the Pass-3 enforcement engine.
Ported from wpl-validator-ts/src/enforce/cycle.ts. Pure functions, no I/O. All dates are ISO-8601 strings ("YYYY-MM-DD") treated as UTC midnight.
Summary
Functions
Compute the 1-indexed cycle_day at date given the client's cycle anchor.
Returns nil when the cycle is not projectable (irregular or suppressed).
Compute the calendar date of a plan day given its structural position.
day_offset_in_week is 0-based from Monday (0=Mon, 6=Sun).
Map a WPL day_of_week token to a 0-based offset from Monday. Returns nil for non-weekday tokens.
Types
@type cycle() :: %{ optional(:last_period_start) => String.t() | nil, optional(:length_days) => pos_integer() | nil, optional(:pattern) => String.t() | nil }
Functions
@spec compute_cycle_day(String.t(), cycle()) :: pos_integer() | nil
Compute the 1-indexed cycle_day at date given the client's cycle anchor.
Returns nil when the cycle is not projectable (irregular or suppressed).
@spec day_date_for_plan_position(String.t(), non_neg_integer(), pos_integer(), 0..6) :: String.t()
Compute the calendar date of a plan day given its structural position.
day_offset_in_week is 0-based from Monday (0=Mon, 6=Sun).
Map a WPL day_of_week token to a 0-based offset from Monday. Returns nil for non-weekday tokens.