search

Found

info Overview

Two-way POSIX cron and systemd OnCalendar converter with a 5-fire preview, ready-to-paste .timer unit or crontab line, and non-roundtrip warnings.

📘 How to Use

  1. Pick the conversion direction (cron → systemd or systemd → cron)
  2. Type a cron expression or OnCalendar string into the top field
  3. Choose a timezone and inspect the next 5 fire times
  4. Read the converted expression and .timer unit or crontab line

systemd Timer / cron Converter

5 or 6 fields: minute hour day-of-month month day-of-week (optional leading second).

--
Copied!
--
Copied!
  1. Enter a valid expression to preview the next fire times.
Article

systemd Timer / cron Converter | Round-trip cron ↔ OnCalendar with a 5-fire preview and a ready-to-paste .timer unit

A round-trip converter between POSIX cron expressions and systemd OnCalendar strings, with a preview of the next 5 fire times and a ready-to-drop .timer unit or crontab line. The point is to catch syntax mismatches and "wait, that's not what I meant" schedules before you systemctl enable.

💡 About this tool

If you've ever migrated a crontab to systemd timers, you know the field order is almost — but not quite — the same. cron reads minute hour dom month dow left to right; OnCalendar puts day-of-week up front, then a date triplet, then HH:MM:SS. The conversion is mostly mechanical, but the gotchas are real: MON-FRI becomes Mon..Fri, */15 becomes *:0/15, six-field cron with seconds has no POSIX-cron equivalent, and RandomizedDelaySec has no cron analogue at all.

This tool handles those edges. It expands cron list, range, step, and name forms (JAN-DEC, MON-FRI) and emits the OnCalendar form with leading DOW only when needed. The reverse path parses OnCalendar's .. ranges and 0/N step syntax, strips RandomizedDelaySec into a warning, and writes a 5-field crontab line. Both directions render a preview of the next 5 fires across 9 common timezones, so you can sanity-check against your server's date -u.

The .timer unit template includes Persistent=true and AccuracySec=1min by default — sensible for one-shot tasks but worth overriding for high-frequency timers. Copy the snippet, drop it into /etc/systemd/system/my-task.timer, pair it with a .service unit, and systemctl daemon-reload && systemctl enable --now my-task.timer.

🧐 Frequently Asked Questions

Q. Does six-field cron (with seconds) work? A. Yes — the leading second field is parsed and written into OnCalendar's HH:MM:SS. The tool warns that sub-minute precision is only honored on the systemd side; standard crond ignores anything tighter than a minute.

Q. Why aren't @daily / @reboot accepted? A. The parser handles the explicit * * * * * grid only. @daily is equivalent to 0 0 * * *, so type that. @reboot doesn't map to OnCalendar at all — use OnBootSec= or OnStartupSec= directly in the .timer unit.

Q. What does RandomizedDelaySec become on the cron side? A. It's stripped with a warning. cron has no native jitter knob; you can approximate it by adding sleep $((RANDOM % 60)) inside the script the cron line invokes, but that's a manual rewrite the tool intentionally doesn't perform.

Q. The next-5 preview shows UTC but my server runs in another zone A. The timezone dropdown includes UTC, browser-local, JST, ET, PT, GMT, CET (×2), and BRT. Pick one and the preview recalculates against that zone. To pin the timer itself, add Timezone= to the [Timer] section after copying the snippet.

Q. Does the converter preserve DOW range MON-FRI when going systemd→cron? A. The OnCalendar Mon..Fri is expanded to the list 1,2,3,4,5. The crontab line shows the explicit list rather than the range form. Tidy it up to 1-5 by hand if you prefer the shorter syntax — both are accepted by every mainstream crond implementation.

Q. Why does my expression error out? A. Parse failures land in the red error panel under the input, with the field name and the invalid token (Invalid value: garbage, Date must be Y-M-D). The output stays at -- until the input is valid.

📚 Fun Facts

systemd timers landed around v183 in 2012, but crond predates Linux itself — cron(8) shipped with Version 7 Unix in 1979 and has been carrying the world's batch jobs for over four decades. The two systems coexist because they're built for slightly different jobs: cron's contract is "run this command line on this schedule", while a systemd timer is just a trigger that activates a separately-defined .service unit. That extra indirection is overhead for a one-liner, but it pays back when you want resource limits, environment files, dependency ordering, or journal-backed logs.

OnCalendar's *-*-* *:0/15 syntax is sometimes mistaken for ISO 8601, but it's a systemd extension layered on top of the ISO date-time skeleton. Real ISO 8601 has no * wildcard and no 0/N step operator — those are pure systemd. If you want to read what a timer is actually going to do, systemd-analyze calendar 'Mon..Fri *-*-* 09:30:00' resolves the expression and dumps the next firings, which is the same calculation this tool does in your browser.