Skip to content

Every day at midnight cron: what 0 0 * * * means and whose midnight it is

Runs in your browser — nothing you paste leaves this page. How we prove that

Cron Expression Tester playground

Example

Five fields — minute, hour, day of month, month, day of week. Macros like @daily are supported too.

Results update as you type — press Enter to run now.

Timezone
fig. 04 — cron-expression-tester · scheduling Valid
Result

At 00:00.

Minute0
Hour0
Day of month*
Month*
Day of week*
Next runs
  • Computed in your browser, in your timezone.

`0 0 * * *` fires once a day at 00:00. The engine reads it as: At 00:00.

Field by field

Minute 0 and hour 0 pin the time to 00:00; day of month, month and day of week are wildcards, so it runs every day of the year. The macros @daily and @midnight are defined as exactly this expression in cron implementations that support them.

The parser on this page reads it as: At 00:00. The next run times in the panel above are computed in your browser, in your own timezone, so they are not printed in this text.

Whose midnight?

Cron runs in the timezone of the cron daemon, normally the server's system zone. On a cloud VM or a container image that is very often UTC, so a nightly job written for local midnight in India actually runs at 05:30 IST, and one meant for New York runs at 19:00 or 20:00 the previous evening depending on daylight saving. Check with timedatectl or date, and set CRON_TZ= in the crontab if your cron supports it.

GitHub Actions schedules are always UTC, and Kubernetes CronJobs use the controller's zone unless the timeZone field is set (stable since Kubernetes 1.27).

Example and pitfalls

0 0 * * * flock -n /run/lock/nightly-backup.lock /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1 is the textbook nightly backup. Midnight is crowded: log rotation, certificate renewals and every other daily job tend to pile up there, so shifting non-urgent work to an odd minute, such as 23 2 * * *, spreads the load. If the job builds a report for the previous day, compute that date explicitly rather than assuming the job always starts after midnight; a delayed run that slips can process the wrong day.

Midnight is outside the 01:00–03:00 window where most zones change their clocks, so daylight saving rarely skips or repeats this run, but a few zones do switch at midnight.

systemd, Kubernetes and GitHub Actions

systemd: OnCalendar=daily, the same as *-*-* 00:00:00; Persistent=true catches up a run missed while the host was off, which plain cron does not do (anacron exists for that). Kubernetes accepts 0 0 * * * or @daily; GitHub Actions needs the five-field form. For a daytime equivalent see every day at noon.

FAQ

Questions, answered.

Tap a question to expand the answer.

Yes, in cron implementations that support macros both are defined as 0 0 * * *. GitHub Actions does not accept macros.

The cron daemon uses the server timezone, which is often UTC on cloud hosts and containers. Either convert your local midnight to UTC or set CRON_TZ, or the timeZone field on a Kubernetes CronJob.

More free, private DevOps tools.

The Cron Expression Tester is one tool in OpsCanopy — a growing canopy of browser-based validators, converters and testers that never touch a server.

New to Linux?  Read the Linux guide →

42 free tools, every one offline-capable — opscanopy.com works with no signup and nothing uploaded.

Scheduling on Linux? Pair this with the Cron to systemd Converter, or browse the full tools directory.

Not affiliated with or endorsed by any cron implementation. Format names are used only to describe what this tool reads. OpsCanopy is free and open.