YmerNode.Schedules.Lifetime (Ymer Node v0.5.0)

Copy Markdown View Source

A schedule's lifetime — how far into the future it keeps firing — read from what a caller gives add or update into the one instant it ends.

Every schedule ends. A missing lifetime is the ceiling, 90 days, and a longer one is cut to it: nothing is refused for being long, because the node can serve the request and the answer states the end it set. The ceiling is a bound against accidents — a schedule nobody remembers, firing for ever.

The grammar

One ISO-8601 field. A span starts with P — P30D, PT12H, P2W, P1M — and runs from the moment of the call. Anything else is an instant: with an offset or Z it means exactly that; without one it is read in the node's time zone, the zone the cron expression is read in. A bare date is refused, because whether it means the start of that day or its end is a guess.

An offset-less instant the clock passes twice — in the hour a fall-back repeats — is its first pass, as it is for a cron expression (YmerNode.Schedules.Cron). One the clock never shows — in the hour a spring-forward skips — is refused, with a hint to give an offset.

A lifetime that ends at or before the call is refused rather than stored as a schedule expired the moment it exists: a span of nothing, a negative span or an instant already past is a mistake best found at the keyboard.

The end is computed in UTC and truncated to the second, which is how the schedule's row holds it.

Summary

Functions

The instant a lifetime given at now ends, in UTC — nil meaning the ceiling.

Functions

ends_at(lifetime, now, zone)

The instant a lifetime given at now ends, in UTC — nil meaning the ceiling.

Examples

iex> YmerNode.Schedules.Lifetime.ends_at(nil, ~U[2026-10-01 00:00:00Z], "Etc/UTC")
{:ok, ~U[2026-12-30 00:00:00Z]}

iex> YmerNode.Schedules.Lifetime.ends_at("P30D", ~U[2026-10-01 00:00:00Z], "Etc/UTC")
{:ok, ~U[2026-10-31 00:00:00Z]}

iex> YmerNode.Schedules.Lifetime.ends_at("P1Y", ~U[2026-10-01 00:00:00Z], "Etc/UTC")
{:ok, ~U[2026-12-30 00:00:00Z]}

iex> YmerNode.Schedules.Lifetime.ends_at("2026-10-02T12:00:00+03:00", ~U[2026-10-01 00:00:00Z], "Etc/UTC")
{:ok, ~U[2026-10-02 09:00:00Z]}