Crontab to systemd OnCalendar Converter
Convert between standard 5-field crontab syntax and systemd timer OnCalendar= expressions, in either direction, including the common step, range, list and shortcut forms.
Crontab expression
systemd OnCalendar
Common patterns
| Crontab | systemd OnCalendar |
|---|---|
| 0 * * * * | *-*-* *:00:00 |
| 0 0 * * * | *-*-* 00:00:00 |
| 0 0 1 * * | *-*-01 00:00:00 |
| 0 0 1 1 * | *-01-01 00:00:00 |
| */15 * * * * | *-*-* *:00/15:00 |
| 0 9 * * 1-5 | Mon..Fri *-*-* 09:00:00 |
How to use this tool
- Pick a direction: Crontab → systemd to convert a crontab line into an
OnCalendar=value, or systemd → Crontab to go the other way. - Type or paste the expression, or click a preset to see a worked example.
- The result updates as you type. Read any note underneath — it flags things that don’t survive the conversion, like seconds precision or a year component.
- Copy the result into your
crontab -eline or your systemd.timerunit’s[Timer]section. - If both day-of-month and day-of-week are restricted in your crontab line, read the warning carefully — the two systems combine those conditions differently.
A systemd timer’s OnCalendar= directive covers the same ground as crontab’s five time fields, but the grammar is different enough that a manual line-by-line translation is where most mistakes happen. The overall shape is DayOfWeek Year-Month-Day Hour:Minute:Second, with each component individually optional and defaulting to “any” when left out. Crontab’s minute hour day-of-month month day-of-week maps onto that shape once you know where each field goes and how the punctuation changes.
The punctuation is the main thing to relearn. Crontab uses a single dash for a range, like 1-5 for Monday through Friday. systemd uses two dots, Mon..Fri. Both systems use a comma for a list and a slash for a step, so */15 in crontab and 0/15 or */15 in systemd mean the same thing: starting at zero, repeat every 15 units. Weekday names also shift convention — systemd always uses three-letter capitalized names (Mon, Tue, and so on), while crontab accepts either numbers (with Sunday as 0, and 7 also accepted as an alias for Sunday in most cron implementations) or lowercase names.
Weekly schedules deserve a specific warning: crontab’s @weekly shortcut fires on Sunday at midnight, because crontab treats Sunday as day 0, the start of its week. systemd’s weekly shortcut fires on Monday at midnight, because systemd’s calendar model is ISO-8601 and treats Monday as the first day of the week. If you convert @weekly literally you will get a schedule that runs on a different day than the one you started with, unless you explicitly ask for Sunday.
There is a real semantic gap when a crontab line restricts both day-of-month and day-of-week at once, for example 0 9 15,30 * 1-5. Vixie cron resolves that with OR logic: the job runs when either condition is true (the 15th or 30th of the month, OR any weekday). systemd’s calendar expressions have no equivalent OR between a date and a weekday — a weekday prefix and a date component are combined with AND, meaning both must match simultaneously. There is no direct single-line translation for the OR case; you generally need two separate timer units, one per condition, if you need to preserve the original behavior exactly. This tool flags that situation rather than silently producing a wrong answer.
Seconds are the other asymmetry, in the opposite direction: systemd calendar expressions carry a seconds field and crontab does not. A value like *:0/30:30 (every 30 seconds within each half-minute window) has no crontab equivalent at all — cron’s finest resolution is one minute. Converting systemd to crontab in that case necessarily drops precision, and this tool tells you when that happened rather than quietly rounding.
Frequently asked questions
Why did my @weekly cron job move to a different day after converting?
Because crontab’s @weekly means Sunday at midnight (crontab’s week starts on Sunday), while systemd’s weekly shortcut means Monday at midnight (systemd follows ISO-8601, which starts the week on Monday). They are not the same schedule. If you need Sunday specifically, write it out as Sun *-*-* 00:00:00 rather than using the weekly shortcut.
How do I write “every 15 minutes” as an OnCalendar value?
*-*-* *:00/15:00. The minute field uses start/step syntax — 00/15 means minutes 0, 15, 30 and 45 past every hour, which is exactly what crontab’s */15 means.
Can I convert a crontab line that restricts both day-of-month and day-of-week?
Not with a single systemd timer that behaves identically. Crontab combines the two with OR (either condition triggers the job); systemd combines a weekday prefix and a date with AND (both must be true). This tool detects the case and warns you — the practical fix is usually two separate timer units, one per condition.
Does systemd support seconds in a schedule?
Yes — the third component of the time part, e.g. 09:00:30, or a repeating form like *:0/30:00 for every 30 minutes on the dot. Crontab has no equivalent; its finest resolution is one minute, so converting a systemd expression with meaningful seconds down to crontab always loses precision, and this tool calls that out.
What is the systemd equivalent of crontab’s @reboot?
There isn’t a calendar equivalent, because @reboot isn’t a time at all. In systemd, use a .service unit with WantedBy=multi-user.target (or a dedicated .timer with OnBootSec=) instead of OnCalendar= — OnBootSec=0 runs the unit once, shortly after boot.