Free Handy Tools

Cron Expression Parser

Five fields: minute, hour, day-of-month, month, day-of-week.

In plain English

Every 15 minutes, every day.

  • Minute 0–590, 15, 30, 45
  • Hour 0–23every
  • Day of month 1–31every
  • Month 1–12every
  • Day of week 0–6every
Fires per matching day96
Matching days a year365
Fires a year35,040

Next fire times

  1. Mon 7 Sep 2026, 04:30UTC
  2. Mon 7 Sep 2026, 04:45UTC
  3. Mon 7 Sep 2026, 05:00UTC
  4. Mon 7 Sep 2026, 05:15UTC
  5. Mon 7 Sep 2026, 05:30UTC

Standard cron has five fields and no year field, so a schedule can only repeat — a one-off date has to be handled by the job itself or by at. The times listed above are wall-clock times in the zone you picked, which is the zone the daemon reads: a container running in UTC fires an hour earlier than your desk clock for half the year.

Five fields, no year, and a great deal of trust

A cron expression is five numbers standing in for a sentence, and it goes wrong in ways nothing warns you about: the daemon accepts anything syntactically legal and runs it quietly for months. This tool reads one back in English, lists the next times it will fire, and counts how often that is over a year.

The fields are minute, hour, day-of-month, month and day-of-week, in that order. There is no year field and no seconds field, so every standard expression repeats forever: a single run on a fixed date is not something crontab can say, and a six-field expression belongs to Quartz or Spring instead.

Names work in the last two fields: JAN through DEC and SUN through SAT, so 30 8 * * MON-FRI is the schedule 30 8 * * 1-5. Sunday answers to both 0 and 7.

The 13th or a Friday, never both required

When day-of-month and day-of-week are both narrowed, cron combines them with OR rather than AND. So 0 0 13 * 5 is not Friday the 13th; it is midnight on every 13th and on every Friday. Asked for the next five runs after Saturday 15 August 2026, it answers 21 and 28 August, 4 and 11 September, then Sunday 13 September — four Fridays and a Sunday.

Across a year that expression fires 62 times: 52 Fridays plus 12 thirteenths, less the two dates that are both. An AND reading would fire twice. Leave either field as * and the OR never applies: 0 0 13 * * gives the expected 12 runs, 0 0 * * 5 gives 52.

Friday the 13th therefore has no expression in standard cron. The usual answer is to fire on every 13th and let the job check the weekday itself, with a one-line guard at the top of the script.

Two schedules a single character apart

Compare 0 0 * * 0, which runs 52 times a year, with * * * * 0, which runs every minute of every Sunday: 1,440 times a day and 74,880 times a year. The only difference is an open minute and hour field, and nothing complains until the logs fill up.

Steps count from the bottom of the field and restart at its boundary rather than running continuously. So */15 gives minutes 0, 15, 30 and 45, or 96 runs a day, while */7 gives 0, 7, 14 and on to 56 before jumping back to 0 — a four-minute gap across every hour boundary. A list is different again: 5,10 fires twice an hour, five minutes apart.

In the month field a step counts from January, so 0 0 1 */3 * means January, April, July and October rather than every three months from today: from August 2026 its next run is 1 October.

Dates that never arrive, and clocks that move

An entry of 0 0 31 * * fires in seven months a year, skipping April, June, September and November without comment. One of 0 0 29 2 * survives on leap years alone: after August 2026 its next runs are 29 February 2028 and 2032. The search looks eight years ahead and returns nothing at all when nothing matches, which is the honest answer for 0 0 30 2 *.

Cron fires on wall-clock time in whatever zone the daemon runs in, so the list can be read as UTC or against your own offset. That matters twice a year: a 02:30 job may be skipped when the clocks spring forward and run twice when they go back. Anything scheduled between 01:00 and 03:00 is worth moving; a UTC host is immune.

@daily, seconds, and clocks that move

What do @daily and @reboot actually stand for?

They are nicknames some implementations accept in place of the five fields. @hourly is 0 * * * *, @daily is 0 0 * * *, @weekly is 0 0 * * 0 and @monthly is 0 0 1 * *. @reboot is different in kind: it fires once when the daemon starts, on no schedule at all, and it is not portable.

Can cron run something every 30 seconds?

Not by itself, because the smallest field is a minute. The workarounds are two entries where the second sleeps 30 seconds first, a job that loops internally for a minute, or a systemd timer, which takes an interval of 30 seconds.

Why is my job running twice within the same minute?

Almost always two crontabs rather than one misread expression: a system-wide entry and a user entry, or the same deployment on two hosts pointed at one database. Cron starts a job once per matching minute, so a genuine duplicate means a second source.

Will these times match my server to the second?

They match the minutes your server will select, which is what cron guarantees. The exact second depends on the daemon and on load, and a slow run still going when the next is due overlaps with itself — long jobs want a lock file, not a wider gap.

Where does the output of a cron job go?

To mail, by default. Anything the job writes to standard output or standard error is emailed to the crontab owner, and on a host with no working mailer it is discarded — which is how a failing job stays silent for months. Redirect both streams to a log file somebody reads.

Why does my job work by hand and fail under cron?

Because cron gives it almost no environment: a short PATH, no shell profile, and a working directory that may not be the one you assume. Use absolute paths to every binary and every file, and set what the script needs at the top of the crontab rather than relying on your login shell.

What does 0 24 * * * run?

Nothing, ever. The hour field runs from 0 to 23, so 24 matches no hour at all, and midnight is hour 0 of the following day.

Can I put comments in a crontab?

Yes — a line beginning with # is ignored, and one line above each entry saying what the job does and who to ask about it is the cheapest documentation on the machine.