# `WardrikTriggers.Clock`

Computes a trigger's next run from a cron expression in a time zone, or from an interval.

    {:ok, clock} = WardrikTriggers.Clock.parse("0 18 * * *")
    WardrikTriggers.Clock.next(clock, "Europe/Berlin", ~U[2026-10-22 09:00:00Z])
    #=> ~U[2026-10-22 16:00:00Z]

A cron time skipped by a clock change runs at the first instant after the gap. A time repeated by
a clock change runs on its first pass only.

# `t`

```elixir
@type t() :: {:cron, Crontab.CronExpression.t()} | {:interval, pos_integer()}
```

# `next`

```elixir
@spec next(t(), String.t(), DateTime.t()) :: DateTime.t()
```

Returns the next run after `from`, in UTC. A cron expression is read in `timezone`.

# `parse`

```elixir
@spec parse(String.t()) :: {:ok, t()} | {:error, String.t()}
```

Parses `every`: a cron expression, as `0 9 * * 1` or `@daily`, or an interval, as `30m`.

An interval is a count and a unit (`s`, `m`, `h` or `d`) of at least a minute. `@reboot` is
rejected.

# `zone?`

```elixir
@spec zone?(String.t()) :: boolean()
```

Returns whether `timezone` names a time zone, as `Europe/Berlin`.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
