Check a systemd timer OnCalendar= value and see its next run times, or convert cron
Runs in your browser. Nothing you type is sent anywhere. Checked against sources on 17 Oct 2026.OnCalendar= tells a systemd timer when to fire, in the form weekdays year-month-day hour:minute:second. Type a value and see its normalized form and next 5 run times exactly as systemd-analyze calendar prints them, or paste a crontab line to get the OnCalendar= value with ready .timer and .service units.
Type the OnCalendar= value, such as Mon..Fri 09:00 or weekly, or tap an example.
Read the normalized form and the next five times it fires, as systemd-analyze calendar prints them.
Or switch to Cron to timer, paste a crontab line and get the OnCalendar= value with .timer and .service units.
Copy the units into /etc/systemd/system and run systemctl enable --now name.timer.
systemd timers replace cron on most Linux servers, but the OnCalendar= syntax is easy to get subtly wrong: is 9:00 every day or only weekdays, does */15 work, when does the job first run? This page answers by computing the schedule the way systemd does.
The syntax in one table.
| You write | systemd reads | Runs |
|---|---|---|
| daily | *-*-* 00:00:00 | Every day at midnight |
| Mon..Fri 09:00 | Mon..Fri *-*-* 09:00:00 | Weekdays at 9 am |
| *:0/15 | *-*-* *:00/15:00 | Every 15 minutes |
| *-*-01 03:30 | *-*-01 03:30:00 | The 1st of each month at 3:30 |
| *-*~01 | *-*~01 00:00:00 | The last day of each month |
| Sat *-*~07/1 | Sat *-*~07/1 00:00:00 | The last Saturday of each month |
Weekdays come first, then the date as year-month-day, then the time; a missing date means every day and a missing time means midnight. Lists use commas, ranges two dots and repetitions a slash. A tilde instead of the last dash counts days from the end of the month.
Cron to timer. Paste a crontab line, macros such as @daily included, and get the equivalent OnCalendar= value, the next 5 runs, and a .timer and .service pair ready for /etc/systemd/system. One difference matters: when a cron line restricts both the day of month and the day of week, cron runs when either matches, while systemd needs both; the page warns and suggests two OnCalendar= lines.
Time zone. Times are worked out in UTC. A timer without a zone runs in the server's local time, so on a server set to UTC the times shown are exact; add UTC to the value to pin it.
How it was checked. For 48 test values and 22 converted crontab lines, the normalized form and next 5 runs match systemd 255's own systemd-analyze calendar, invalid values are refused where systemd refuses them, and every converted cron line fires at the same instants as cron-parser computes for the original. Everything runs in your browser.
Use OnCalendar=*:0/15, which systemd normalizes to *-*-* *:00/15:00 and fires at minutes 0, 15, 30 and 45 of every hour. For a fixed interval since the last run instead of clock times, use OnUnitActiveSec=15min in the timer. Type either schedule here to see the next runs.
Mon..Fri limits the timer to weekdays, *-*-* means any year, month and day, and 09:00 is the time, with seconds defaulting to 00. Together the timer fires at 9 am Monday to Friday, in the server's local time zone unless UTC or another zone is added at the end.
Paste the crontab line on the Cron to timer tab. The five time fields become an OnCalendar= value, for example 30 2 * * 1-5 becomes Mon..Fri *-*-* 02:30:00, and the command becomes ExecStart= in a .service file. Save both units, then run systemctl daemon-reload and systemctl enable --now with the timer name.
Use a tilde in place of the last dash: OnCalendar=*-*~01 fires on the last day of every month at midnight, and *-*~03 on the third-last day. Combined with a weekday, Sat *-*~07/1 fires on the last Saturday of the month, because only one Saturday falls in the last seven days.
systemd only accepts ranges that run forward from Monday to Sunday, so Fri..Mon is refused. Write the days as a list that wraps by hand, such as Fri..Sun,Mon. Weekday names may be short or long, Mon or Monday, and case does not matter.
With Persistent=true, systemd stores when the timer last fired; if the machine was off at a scheduled time, the job runs once as soon as the timer starts again. Cron simply skips missed runs. The generated .timer file sets Persistent=true because backups and reports usually should not be skipped.
Rates and rules change; check the source before you rely on a figure.
Still stuck? Ask about systemd OnCalendar Tester and anybody who knows can answer. No account needed.
On the related tools: Readability Checker – Flesch reading ease and grade level, with what to change · JSONPath Evaluator – Evaluate a JSONPath expression and get the matching values and their paths.