ISO 8601 duration parser, faithful Elixir port of lean/Planner/Iso8601Duration.lean.
Conforms to ISO 8601-1:2019 §5.5.2.4: canonical order Y → Mo → D → T → H → Mi → S
(each unit at most once), fractions allowed on at most one unit and
only if no smaller unit follows, weeks must stand alone. UTC-elapsed
normalisation (Y = 365d, Mo = 30d, W = 7d, D = 86_400 s);
civil time is out of scope.
Originally written so the Lean spec could be exercised with PropCheck
against the Timex oracle and a strict spec recogniser (still is —
see test/taskweft/iso8601_duration_prop_test.exs); promoted from
test/support into lib so Taskweft.JSONLD.Loader.validate/2 can
reject a malformed action duration at load time instead of letting
it reach the NIF. The C++ NIF port lives upstream in
taskweft-nif/standalone/tw_temporal.hpp and must match this
module's behaviour.
Summary
Types
@type component() :: %{ unit: unit(), whole: non_neg_integer(), frac_milli: non_neg_integer() }
@type unit() :: :y | :mo | :w | :d | :h | :mi | :s
Functions
@spec total_milliseconds([component()]) :: non_neg_integer()
@spec total_seconds([component()]) :: non_neg_integer()