cron
stableCron expression parser and scheduler that validates expressions, computes next run times, and provides convenience builders for common schedules.
use plugin cron Plugin snippets can be edited in the Playground, but native capabilities are executed locally with the Zolo CLI.
Functions (11)
- parse Parse a cron expression into a table
- is_valid Check if a cron expression is valid
- next_run Get the next run timestamp after a given time
- matches Check if a cron table matches a Unix timestamp
- describe Get a human-readable description of a cron expression
- next_n_runs Get the next N run timestamps
- to_string Convert a cron table back to an expression string
- every_minutes Build a cron table for every N minutes
- every_hours Build a cron table for every N hours
- daily_at Build a cron table for a daily time
- weekly_on Build a cron table for a weekly schedule
From import to result
- 01Import only what you use
- 02Copy the smallest example
- 03Run it with the Zolo CLI
Overview¶
The cron plugin turns standard 5-field cron expressions (minute hour dom month dow)
into schedules you can reason about: validate them, render them in plain English,
and compute the exact Unix timestamps when they will fire. A parsed schedule is a
plain table with string fields (minute, hour, dom, month, dow), so it
carries no hidden state — you pass it back into next_run, matches, or
next_n_runs as a value. Builder helpers like every_minutes, daily_at, and
weekly_on produce the same table without you having to hand-write the expression.
Reach for this plugin whenever you need to drive a task on a wall-clock schedule or
preview when a schedule will next run.
Common patterns¶
Validate before scheduling, then describe what you built so logs are readable:
use plugin cron::{is_valid, parse, describe}
let expr = "0 9 * * 1-5"
if is_valid(expr) {
let schedule = parse(expr)
print("scheduled: {describe(expr)}")
}Build a schedule with a helper and preview its upcoming fire times:
use plugin cron::{daily_at, next_n_runs}
use plugin datetime::{now_unix, format_iso8601}
let backup = daily_at(2, 30)
let runs = next_n_runs(backup, now_unix(), 3)
print("next backups:")
print(format_iso8601(runs[1]))
print(format_iso8601(runs[2]))
print(format_iso8601(runs[3]))Check whether a schedule should fire at the current minute:
use plugin cron::{parse, matches}
use plugin datetime::{now_unix}
let schedule = parse("*/15 * * * *")
if matches(schedule, now_unix()) {
print("running the quarter-hour job")
}Parse a cron expression into a table
Parses a standard 5-field cron expression (minute hour dom month dow) and
returns a table with minute, hour, dom, month, and dow string
fields. Supports *, ranges (1-5), lists (1,15), and steps (*/5).
use plugin cron::{parse, describe}
let expr = parse("0 9 * * 1-5")
print(describe("0 9 * * 1-5"))A parsed table exposes each field as a normalized string, so you can inspect the schedule directly:
use plugin cron::{parse}
let schedule = parse("*/10 8-17 * * 1-5")
print("minute field: {schedule["minute"]}")
print("hour field: {schedule["hour"]}")
print("dow field: {schedule["dow"]}")Check if a cron expression is valid
Returns true if the cron expression has valid syntax and field ranges.
use plugin cron::{is_valid}
print(is_valid("*/5 * * * *"))
print(is_valid("60 * * * *"))
print(is_valid("not a cron"))Get the next run timestamp after a given time
Returns the next Unix timestamp (in seconds) when the cron schedule fires
after from_unix. Searches up to 4 years ahead.
use plugin cron::{parse, next_run}
use plugin datetime::{now_unix, format_iso8601}
let schedule = parse("0 */2 * * *")
let now = now_unix()
let next = next_run(schedule, now)
print("next run: {format_iso8601(next)}")Chain next_run from its own result to walk forward through fire times one at a
time:
use plugin cron::{weekly_on, next_run}
use plugin datetime::{now_unix, format_iso8601}
let standup = weekly_on(1, 9, 30)
let first = next_run(standup, now_unix())
let second = next_run(standup, first)
print("this week: {format_iso8601(first)}")
print("next week: {format_iso8601(second)}")Check if a cron table matches a Unix timestamp
Returns true if the given Unix timestamp matches the cron schedule (ignoring seconds).
use plugin cron::{parse, matches}
use plugin datetime::{parts_to_unix}
let schedule = parse("30 14 * * *")
let ts = parts_to_unix(2026, 6, 15, 14, 30, 0)
print("matches 14:30: {matches(schedule, ts)}")Get a human-readable description of a cron expression
Returns a human-readable English description of a cron expression, such as
"every 5 minutes" or "at minute 30, at hour 14, on Monday".
use plugin cron::{describe}
print(describe("*/5 * * * *"))
print(describe("0 9 * * 1"))
print(describe("30 14 1 * *"))Pair describe with a builder to confirm that a generated schedule means what you
expect before relying on it:
use plugin cron::{every_hours, to_string, describe}
let sched = every_hours(6)
print(describe(to_string(sched)))Get the next N run timestamps
Returns a table of the next count Unix timestamps when the schedule fires.
count must be between 0 and 1000.
use plugin cron::{parse, next_n_runs}
use plugin datetime::{now_unix, format_iso8601}
let schedule = parse("0 8 * * 1-5")
let runs = next_n_runs(schedule, now_unix(), 3)
print("next 3 runs:")
print(format_iso8601(runs[1]))
print(format_iso8601(runs[2]))
print(format_iso8601(runs[3]))Convert a cron table back to an expression string
Converts a parsed cron table back into a 5-field expression string.
use plugin cron::{every_minutes, to_string}
let sched = every_minutes(15)
print(to_string(sched))Build a cron table for every N minutes
Returns a cron table that fires every minutes minutes (1–59). Equivalent
to */N * * * *.
use plugin cron::{every_minutes, to_string}
let sched = every_minutes(15)
print(to_string(sched))Build a cron table for every N hours
Returns a cron table that fires every hours hours (1–23) at minute 0.
Equivalent to 0 */N * * *.
use plugin cron::{every_hours, to_string}
let sched = every_hours(6)
print(to_string(sched))Build a cron table for a daily time
Returns a cron table for a daily schedule at the given hour (0–23) and optional minute (0–59, defaults to 0).
use plugin cron::{daily_at, to_string}
let morning = daily_at(9, 0)
print(to_string(morning))
let afternoon = daily_at(14, 30)
print(to_string(afternoon))Build a cron table for a weekly schedule
Returns a cron table for a weekly schedule. day_of_week is 0 (Sunday)
through 6 (Saturday). hour and minute default to 0.
use plugin cron::{weekly_on, to_string}
let monday_morning = weekly_on(1, 9, 0)
print(to_string(monday_morning))