cron schedule builder
Click together a schedule in plain words and get the systemd timer, the cron line and the next 5 run times.
Last updated
In short: Pick how often a job should run (every few minutes, daily, on chosen weekdays, or monthly on a day, the last day or the first Monday) and this builder writes both formats: a systemd OnCalendar= line such as Fri *-*-* 20:00:00 and a crontab line such as 0 20 * * 5. It also shows the schedule as a sentence and the next 5 run times in your time zone, so you can check it before you save anything.
Your input never leaves your browser. Everything is calculated on your device; nothing you type is sent to a server.
Review generated files before you use them. Provided as-is — see Terms.
How does the cron schedule builder work?
Linux has two common ways to run a job on a schedule. Cron reads one line per
job from your crontab (open it with crontab -e): five time fields, then the command.
The fields are minute, hour, day of the month, month and day of the week, and *
means "any". So 0 20 * * 5 reads as "minute 0 of hour 20, on any date, when it is a
Friday". The format is described in
crontab(5).
A systemd timer is a small file next to a .service file with the
same name. The service says what to run; the timer says when, in an OnCalendar= line
that reads like a date with wildcards: weekday year-month-day hour:minute:second. So
the same Friday job becomes Fri *-*-* 20:00:00. Ranges use two dots
(Mon..Fri, 09..16), /15 means "every 15", and
~ counts back from the end of the month. The grammar is in
systemd.time(7), the timer
options in systemd.timer(5).
The two formats disagree in one place that trips up many people. When you set both a day of the
month and a weekday, systemd needs both to match (Mon *-*-01..07 is the first
Monday), but cron runs when either matches (1-7 * 1 is days 1 to 7 plus every
Monday). That is why the builder adds a small test in front of the cron command for "first
Monday" and "last day" schedules.
Before you rely on a schedule, check it. On the machine itself,
systemd-analyze calendar --iterations=5 'Fri *-*-* 20:00:00' prints the next 5 runs,
and after enabling a timer, systemctl --user list-timers shows when it fires next.
The run times on this page are computed the same way, in your browser.
Worked examples
Every Friday at 20:00
Input Weekly, Friday ticked, time 20:00 gives OnCalendar=Fri *-*-* 20:00:00
cron: 0 20 * * 5 /usr/local/bin/your-script.sh
systemd writes the day name first, then the date (*-*-* means any year, month and day), then the time with seconds. Cron counts the weekday as a number with 0 = Sunday, so Friday is 5.
Every 15 minutes during office hours
Input Every few minutes: 15, only between 09:00 and 17:00, Monday to Friday gives OnCalendar=Mon..Fri *-*-* 09..16:00/15:00
cron: */15 9-16 * * 1-5 /usr/local/bin/your-script.sh
The hour range ends at 16, not 17: hour 16 covers 16:00, 16:15, 16:30 and 16:45, so the last run is at 16:45. Writing 09..17 (or 9-17 in cron) would add runs at 17:00, 17:15, 17:30 and 17:45.
On the last day of every month at 23:00
Input Monthly, the last day, time 23:00 gives OnCalendar=*-*~01 23:00:00
cron: 0 23 28-31 * * [ "$(date -d tomorrow +\%d)" = 01 ] && /usr/local/bin/your-script.sh
In systemd, ~01 means the first day counted back from the end of the month (note: no dash before the ~). Cron has no such field, so the cron line starts on days 28 to 31 and a small test only lets the job through when tomorrow is the 1st.
Frequently asked questions
How do I write a cron job that runs every Friday at 8 pm?
Use 0 20 * * 5 followed by the command: minute 0, hour 20, any day of the month, any month, weekday 5 (Friday). Add it with crontab -e. The systemd timer equivalent is OnCalendar=Fri *-*-* 20:00:00.
How do I run a cron job on the last day of the month?
Cron has no "last day" field. The usual trick is 0 23 28-31 * * [ "$(date -d tomorrow +\%d)" = 01 ] && command: it starts on days 28 to 31 and only continues when tomorrow is the 1st. A systemd timer says it directly with OnCalendar=*-*~01 23:00:00.
How do I run a job on the first Monday of the month?
In systemd: OnCalendar=Mon *-*-01..07 09:00:00, because systemd requires the weekday AND the date to match. In cron, 0 9 1-7 * 1 does not work: when both day fields are set, cron runs on days 1 to 7 OR on any Monday. Use 0 9 1-7 * * with the test [ "$(date +\%u)" = 1 ] && in front of the command instead.
Why does */7 in the minute field not run every 7 minutes?
Because the count restarts every hour: */7 means minutes 0, 7, 14 ... 56, and then 0 again four minutes later. Only steps that divide 60 (1, 2, 3, 4, 5, 6, 10, 12, 15, 20, 30) give an even rhythm, which is why the builder offers only those. The same goes for hours and 24.
Which time zone does my cron job or timer use?
The server's system time zone, which timedatectl shows. A systemd timer can use another zone when you add it at the end, for example OnCalendar=*-*-* 09:00:00 Europe/Brussels. Cron has no time zone field; cronie accepts a CRON_TZ= line, Debian and Ubuntu cron does not.
What happens to a job at 02:30 when the clocks change?
In spring the clock jumps from 02:00 to 03:00 in most of Europe, so 02:30 does not exist that day: systemd skips the run and most cron versions run it right after the jump. In autumn 02:30 happens twice and the job still runs once. Schedule jobs outside 02:00 to 03:00 to avoid the question.
Should I use cron or a systemd timer?
Both are fine for simple jobs. A timer catches up after downtime (Persistent=true), logs to the journal, never starts a second copy while the first is still running, and can spread load with RandomizedDelaySec=. Cron is one line in one file. The builder gives you both, so you can choose.