Migrating from crontab: five everyday schedules, translated into Kairos
If you arrived from the Kairos 1.0 announcement , this is the hands-on one: take a crontab you already have and translate it. First, the honest part: if your jobs are plain fixed-time repeats, stay on cron. "Every hour", "3am daily" — there is nothing to gain from rewriting them. You reach for a schedule language when you hit one of these: "end of month" won't fit; "business day" won't fit; the job started running at the wrong hour after a server move; nobody can tell you what was skipped during an outage. All examples below use one premise — the 2026 US federal holidays (observed dates) — and were run on the reference implementation. The premise is declared once and reused: premise US { calendar-system: Gregorian tz: "America/New_York" wkst: Sun } @US holidays2026 = [2026-01-01, 2026-01-19, 2026-02-16, 2026-05-25, 2026-06-19, 2026-07-03, 2026-09-07, 2026-10-12, 2026-11-11, 2026-11-26, 2026-12-25] covering: 2026..2026 satSun = everyDay |> filter(d => weekday(d) == Sat or weekday(d) == Sun) bizDay = everyDay \ (satSun | holidays2026) 1. 0 9 * * 1-5 — weekdays at 9 Two things this cron line does not say. Which 9 o'clock — it's whatever timezone the host happens to have, which is exactly how "the batch moved an hour after we containerized" happens. And holidays — cron has no such concept. bizDay |> at(T09:00) Labor Day week (Sep 4–10, 2026): 2026-09-04T09:00 2026-09-08T09:00 2026-09-09T09:00 2026-09-10T09:00 Monday 9/7 (Labor Day) and the weekend are skipped. "New York, 9:00" is written in the definition, so it survives any host move. 2. 55 23 28-31 * * + a script — month-end at 23:55 cron has no "last day", so the folk remedy is to wake up on the 28th–31st and let a script check "is tomorrow the 1st?". The check disappears into the expression: monthEnd |> at(T23:55) #=> 2026-09-30T23:55 2026-10-31T23:55 2026-11-30T23:55 2026-12-31T23:55 3. Payday: the 25th, previous business day if it falls on a weekend or holiday This is where migration starts to pay off — cron canno