Cron Expression Explainer
Paste a crontab line, read it in English, and see exactly when it fires next — in your timezone or in UTC, which is what your server is probably using.
Expression
What it means
Working out the next runs…
The five fields
A standard crontab line is five space-separated fields. A sixth field at the front means seconds, which Quartz and node-cron support but plain crontab does not.
┌───────── minute (0 - 59) │ ┌─────── hour (0 - 23) │ │ ┌───── day of month (1 - 31) │ │ │ ┌─── month (1 - 12, or JAN-DEC) │ │ │ │ ┌─ day of week (0 - 6, or SUN-SAT; 0 and 7 are both Sunday) │ │ │ │ │ * * * * *
The rule that catches everyone
When both the day-of-month and day-of-week fields are restricted, cron fires when either matches — not both. This is in POSIX, it is not a bug, and it surprises people constantly.
So 0 0 13 * FRI is not “Friday the 13th”. It is “midnight on the 13th of every month, and also midnight every Friday” — roughly 64 runs a year instead of one or two. There is no cron expression for Friday the 13th; you schedule 0 0 13 * * and check the weekday inside the job.
The explainer above spells this out whenever both fields are restricted, because reading it back in English is the fastest way to catch it.
Timezones
Cron uses the system timezone of whatever runs it. Almost every server, container image, CI runner and managed scheduler defaults to UTC — Vercel Cron, GitHub Actions and Kubernetes CronJobs all do. If you are in India, a job you wrote as 0 9 * * * thinking “9am” fires at 2:30pm IST.
The UTC toggle above exists for exactly this. Set it, read the fire times, and confirm they are when you meant.
Syntax this tool accepts
*— every value.?is accepted as a synonym in the day fields.5— a single value.1,15,30— a list.9-17— a range. Wrapping ranges like22-2andFRI-MONwork too.*/15— a step.9-17/2— a step within a range.5/15— from 5 onward, every 15.JAN-DECandSUN-SATnames, case-insensitive.- Six fields, where the first is seconds.
It does not accept the Quartz extensions L, W and #. Their meaning varies between schedulers, so the tool refuses them with a clear message rather than guessing and giving you wrong fire times.
Frequently asked
What do the five fields in a cron expression mean?
In order: minute (0-59), hour (0-23), day of month (1-31), month (1-12), day of week (0-6, where 0 is Sunday). A sixth field at the front, if present, is seconds — that is a Quartz and node-cron extension, not standard crontab.
Why does my cron job run more often than I expect?
Almost always the day-of-month and day-of-week rule. When BOTH fields are restricted, cron matches if EITHER one matches, not both. So `0 0 13 * FRI` does not mean 'Friday the 13th' — it means the 13th of every month AND every Friday. To get Friday the 13th you need a day-of-month of 13 and a check inside your script.
What timezone does cron use?
The system timezone of the machine running it, unless overridden. Most servers, containers, and CI runners are set to UTC, which is why a job scheduled for '09:00' fires at 14:30 IST. Vercel Cron, GitHub Actions, and Kubernetes CronJobs all default to UTC. Toggle UTC above to see what your expression actually does there.
What is the difference between */15 and 0/15?
Nothing, in practice. `*/15` means 'every 15th value starting from the lowest', and `0/15` means 'starting from 0, every 15th'. Both give 0, 15, 30, 45. The `*/n` form is standard crontab; `n/m` is a Quartz-ism that many parsers also accept.
Does this tool support L, W and # (last day, weekday, nth)?
No, and it says so rather than guessing. Those are Quartz extensions, not standard crontab, and their semantics differ between implementations. If you need them, check your specific scheduler's documentation — silently mis-parsing them would be worse than refusing.
Built by Himanshu Srivastava, a backend engineer in Bengaluru who has misread the day-of-week field more than once. More in the tools collection.