Paste it in and get the next 8 run times, in your own time zone, plus the traps a quick read of the string will not show you.
It parses the expression the way Vixie/POSIX cron does — 5 fields, or 6 with a leading seconds field — and works out what it means: which value goes in each field, and the next 8 times it would actually fire, computed in wall-clock time for whichever time zone you pick. Nothing you paste in is sent anywhere; the parsing and the date arithmetic both run in your browser.
It exists because a cron string is compact by design, and compact is not the
same as readable. 30 2 * * 1-5 is unambiguous to the program that runs it
and genuinely hard to eyeball at 11pm when you are trying to work out why a
job did or did not run last Tuesday.
Standard cron reads left to right as minute, hour, day of month, month, day
of week. Some schedulers — this tool included — accept an optional leading
seconds field, making six in total. Each field accepts a number, a
comma-separated list, a range (1-5), a step (*/15), or a combination
(10-50/10). Month and day-of-week fields also accept names: JAN-DEC, and
SUN-SAT (or 0-7, where both 0 and 7 mean Sunday).
* means "any value" for that field — * * * * * fires every minute.
*/15 means "every 15th value starting from the field's minimum" — for
minutes, that is :00, :15, :30, :45.
Plain cron — the one in your crontab — is 5 fields, with a floor of one
run per minute. Some tools (this one, plus things like node-cron) accept a
sixth, leading field for seconds, which is the only way to express "every 10
seconds" in cron syntax at all. The two are easy to confuse: 0 30 2 * * *
looks like it might mean 2:30, but with six fields the first 0 is seconds
and the schedule actually fires at 02:30:00 — which, written as 5-field cron,
would be 30 2 * * *. Miscounting the fields is the single most common way to
schedule the right job at the wrong time.
The @ shorthands — @hourly, @daily, @weekly, @monthly, @yearly
(@annually and @midnight are aliases) — expand to fixed standard-cron
expressions and behave identically. @reboot is different; see below.
0 0 13 * 5 reads like "the 13th, if it's a Friday" — Friday the 13th. It is
not. Standard cron treats day-of-month and day-of-week as an OR whenever
both are restricted: the job fires on the 13th of every month and on
every Friday, which for most months is five or six runs instead of the one
you were picturing.
This only bites when both fields are restricted at once. 0 0 13 * * (every
13th, day-of-week left as *) means exactly what it looks like, and so does
0 0 * * 5 (every Friday). It is the combination that silently switches from
AND to OR, and it is one of the oldest surprises in cron — POSIX specifies it,
every major cron implementation follows it, and it still catches people who
learned to program after most POSIX specs did.
Cron schedules in wall-clock time, and wall-clock time is not continuous across a daylight-saving transition. Twice a year, somewhere, a clock either skips an hour or repeats one — and a job scheduled inside that hour has to do something, because "run it anyway" has no unambiguous meaning.
When the clocks spring forward, the skipped hour's wall-clock times do not exist. A job set for 02:30 on the day Europe/Paris jumps from 02:00 to 03:00 simply has no 02:30 to run at — this tool reports that run as skipped rather than silently moving it to 01:30 or 03:30, because either guess would be wrong at least as often as it is right.
When the clocks fall back, the repeated hour's wall-clock times happen twice. This tool follows the convention every cron implementation we know of uses: fire once, at the first occurrence, rather than twice.
The practical fix is boring but reliable: schedule maintenance jobs outside the 00:00-04:00 window where most regions put their DST transition, or run your infrastructure on UTC end to end, where this entire section does not apply.
@reboot is not a monitoring target@reboot runs once, when the machine boots — cron itself guarantees nothing
beyond that, and has no concept of "next run" for it because there isn't one.
That makes it a poor fit for the usual monitoring pattern of "alert me if this
doesn't run on schedule": there is no schedule, so there is nothing to compare
a silence against. If a @reboot job matters — restoring state after a crash,
say — the thing worth monitoring is usually the state it restores, not the
boot event itself.
No. There is no signup and no rate limit worth mentioning, because nothing here calls out to a server — the parsing and the next-run calculation both happen in your browser.
No. Nothing you type is sent anywhere, so there is nothing to store and nothing to ask us to delete.
A handful of expressions describe a schedule that fires rarely, or never.
0 0 31 2 * (February 31st) never matches any real date and returns zero
runs. 0 0 29 2 * (February 29th) only matches leap years, so it can take a
few years of search before the next run turns up.
The Quartz-style extras some schedulers add on top of POSIX cron: L (last
day), W (nearest weekday), # (nth weekday of the month), and ? (no
specific value). This tool flags them explicitly rather than silently
misreading them as something else.
Yes, and it is worth checking. Cron on a typical Linux box runs in the system's configured time zone, not necessarily UTC and not necessarily yours. Pick the zone your job's crontab actually runs in, not the zone you happen to be sitting in, or the run times this tool shows will not match reality.
This page answers "what will 30 2 * * 1-5 do?" — a question about the
expression, decided the moment you read the answer. It cannot tell you
whether last night's job actually ran, whether it finished, or whether cron
silently stopped firing three weeks ago because someone edited the wrong
crontab.
Heartbeat monitoring answers the other question. Your job pings a unique URL when it finishes; if that ping goes silent for longer than the schedule plus a grace period allows, you get an alert — email, Slack, webhook, whichever you picked — while it is still one failed run and not a week of missing data. Confirmed from a second independent EU probe region before anyone is paged, so a blip on our side never wakes you up for nothing.
The free plan covers 5 checks and does not expire.