Field by field
0 0 1 1 * reads: At 00:00, on the 1st, only in January.
| Field | Value | Selects |
|---|---|---|
| Minute | 0 | 0 |
| Hour | 0 | 00:00 |
| Day of month | 1 | 1 |
| Month | 1 | January |
| Day of week | * | any day of the week |
Worth knowing
@yearlyand@annuallyare the same schedule.- A job that runs once a year is the one nobody remembers how to fix. Log loudly, and test it by running it by hand.
Variations
0 0 1 4 *Once a year on 1 April - the start of India's financial yearExplain it0 0 1 1,7 *Twice a year, on 1 January and 1 JulyExplain it
The same schedule elsewhere
crontab
0 0 1 1 * /path/to/job.sh
Runs in the machine's local timezone. crontab -e to edit.
GitHub Actions
on:
schedule:
- cron: "0 0 1 1 *"Always UTC. Nothing more often than every 5 minutes, and runs can start late when GitHub is busy.
Kubernetes CronJob
spec: schedule: "0 0 1 1 *" timeZone: "Asia/Kolkata"
timeZone needs Kubernetes 1.27 or later; without it the controller's zone applies, usually UTC.
Spring @Scheduled
@Scheduled(cron = "0 0 0 1 1 *")
Six fields: seconds come first. Days are written as names, which Spring and cron read alike.
Quartz
0 0 0 1 1 ?
One of day-of-month and day-of-week must be ?. Quartz counts days 1-7 from Sunday, so names are safer than numbers.
AWS EventBridge
cron(0 0 1 1 ? *)
Six fields, the last one the year. UTC unless the schedule sets a timezone. Days count from Sunday, as in Quartz.
systemd timer
[Timer] OnCalendar=yearly Persistent=true
Persistent=true runs a job that was missed while the machine was off, once it is back.