Cron Syntax Field by Field
A standard cron expression has 5 fields (minute, hour, day of month, month, day of week), so 0 9 * * 1-5 means 9:00 AM, Monday through Friday. Type an expression above or build one with the buttons to get a plain English explanation and the next 10 run times. Quartz (6 or 7 fields, seconds first) and AWS EventBridge expressions are recognized too.
| Field | Values | Names | Notes |
|---|---|---|---|
| Minute | 0 to 59 | none | First field in Unix cron |
| Hour | 0 to 23 | none | 24-hour clock, 0 = midnight |
| Day of month | 1 to 31 | none | Months without that day are skipped |
| Month | 1 to 12 | JAN to DEC | Names are not case sensitive |
| Day of week | 0 to 7 | SUN to SAT | 0 and 7 are both Sunday |
Each field accepts * (every value), a number, a range 1-5, a list 1,15, a step */15 or a stepped range 9-17/2, and mixes such as 1-5,10. Steps count from the start of the range: */2 in the day of month field means the 1st, 3rd, 5th and so on.
Cron Expression Examples
Explanations produced by this page's explainer. The last three are Quartz expressions (seconds first).
| Expression | Runs |
|---|---|
* * * * * | Every minute |
*/5 * * * * | Every 5 minutes |
0 * * * * | At minute 0 past the hour, every hour |
0 */2 * * * | At minute 0 past the hour, every 2 hours from midnight |
0 9 * * 1-5 | At 9:00 AM, on Monday through Friday |
*/15 9-17 * * 1-5 | Every 15 minutes, 9:00 AM to 5:59 PM, on Monday through Friday |
30 23 * * * | At 11:30 PM |
0 6,18 * * * | At 6:00 AM and 6:00 PM |
0 0 * * 0 | At 12:00 AM, on Sunday |
0 0 1 * * | At 12:00 AM, on day 1 of the month |
0 0 1 */3 * | At 12:00 AM, on day 1 of the month, in January, April, July and October |
0 0 1,15 * 1 | At 12:00 AM, on day 1 and 15 of the month, or on Monday |
0 0 1 1 * | At 12:00 AM, on day 1 of the month, in January |
0 0 9 ? * MON-FRI | At 9:00 AM, on Monday through Friday |
0 0 12 L * ? | At 12:00 PM, on the last day of the month |
0 0 10 ? * 6#3 | At 10:00 AM, on the third Friday of the month |
Day of Month and Day of Week: the OR Rule
When both day fields are restricted, Unix cron runs the job if either one matches. 0 0 1,15 * 1 runs at midnight on the 1st, on the 15th and on every Monday, not only on Mondays that fall on the 1st or 15th. From 21 September 2026 its next runs are Monday 28 September, Thursday 1 October, Monday 5 October, Monday 12 October and Thursday 15 October.
There is a well known quirk: if either day field starts with *, cron switches to AND. 0 0 */2 * 1 therefore runs only on Mondays with an odd date (5 and 19 October 2026 are the next two), because */2 begins with a star. Quartz and AWS avoid the question altogether by requiring ? in one of the two fields.
5 Fields vs 6 or 7: Unix, Quartz and AWS
The same schedule, weekdays at 9:00 AM, in the formats you are most likely to meet:
| System | Expression | Differences |
|---|---|---|
| Unix crontab, Kubernetes CronJob, GitHub Actions | 0 9 * * 1-5 | 5 fields, Sunday = 0 or 7 |
| Quartz (Java) | 0 0 9 ? * MON-FRI | Seconds first, optional year, Sunday = 1, ? required in one day field, L and # allowed |
| AWS EventBridge | cron(0 9 ? * MON-FRI *) | No seconds, year last, Sunday = 1, ? required, runs in UTC unless the schedule sets a time zone |
This page counts the fields to decide: 5 fields are read as Unix cron; 6 fields with ? in the third or fifth position as AWS; other 6 and 7 field expressions as Quartz. Spring's 6-field format uses the Quartz order but numbers Sunday as 0 or 7 and accepts * in both day fields, so check day numbers when you copy between them. GitHub Actions schedules always run in UTC, and the shortest interval it allows is every 5 minutes.
Daylight Saving Time and Next Run Times
Next run times are shown in your browser's time zone, or in UTC if you pick it (AWS expressions are always shown in UTC). In the US, clocks spring forward at 2:00 AM on the second Sunday of March and fall back at 2:00 AM on the first Sunday of November, so the next changes are 1 November 2026 and 14 March 2027.
- Spring forward: 2:00 to 2:59 AM does not exist. A job fixed at 2:30 AM is run right after the change by cronie and Vixie cron, and the list marks it.
- Fall back: 1:00 to 1:59 AM happens twice. A job fixed at 1:30 AM runs once; a job that runs every few minutes runs in both copies of the hour, and the list shows both.
- Servers in UTC have no DST at all, which is why many teams keep server clocks on UTC. cronie also supports a
CRON_TZline per crontab.
To turn a run time into a Unix timestamp, or compare it across zones, use the Unix timestamp converter or the time zone converter.
Cron Guide
minute hour day-of-month month day-of-week. Each field accepts a specific range of values, wildcards, ranges, and step values. For example, 0 9 * * 1-5 means "at 9:00 AM every Monday through Friday." Cron is used for backups, log rotation, database cleanup, report generation, cache invalidation, and any task that needs to run on a schedule.* means "every." */n means "every n units." a-b means a range. a,b,c means a list. ? means "any" (used in some implementations). When both day-of-month and day-of-week are set, most cron implementations use OR logic (runs on either condition).* * * * * every minute. 0 * * * * every hour at :00. */15 * * * * every 15 minutes. 0 0 * * * every day at midnight. 0 9 * * 1-5 weekdays at 9 AM. 0 0 * * 0 every Sunday at midnight. 0 0 1 * * first day of each month at midnight. 0 0 1 1 * January 1st at midnight (yearly). 0 12 * * * every day at noon. 30 23 * * * every day at 11:30 PM. 0 6,12,18 * * * three times a day at 6 AM, noon, and 6 PM.minute hour day-of-month month day-of-week. Quartz Scheduler (Java) uses 6 or 7 fields, adding a Seconds field at the beginning: seconds minute hour day-of-month month day-of-week [year]. AWS EventBridge (CloudWatch Events) also uses 6 fields but in a different format: minute hour day-of-month month day-of-week year. AWS uses ? (question mark) as a wildcard for either day-of-month or day-of-week to avoid conflicts, and does not allow * in both simultaneously. When copying expressions between systems, always check which format is expected. A Quartz expression starting with 0 0 9 * * ? is not valid in standard cron.*/15 * * * * runs at minutes 0, 15, 30, and 45 of every hour, every day. Alternatively, 0,15,30,45 * * * * is equivalent but explicit. If you want every 15 minutes only during business hours: */15 9-17 * * 1-5 runs every 15 minutes between 9 AM and 5 PM on weekdays. Note that */15 starts counting from 0, so it always runs at minute 0. If you want to offset it, use explicit lists: 5,20,35,50 * * * * runs at :05, :20, :35, and :50.crontab -e opens the current user's crontab for editing in the default editor. crontab -l lists all cron jobs for the current user. crontab -r removes all cron jobs (use with caution). sudo crontab -e -u username edits another user's crontab. System-wide cron jobs are in /etc/cron.d/, /etc/cron.daily/, /etc/cron.hourly/, /etc/cron.weekly/, and /etc/cron.monthly/. The main cron log is usually at /var/log/syslog (Ubuntu/Debian) or /var/log/cron (CentOS/RHEL). To redirect cron output: append >> /path/to/log.txt 2>&1 to the command in the crontab.PATH variable only includes /usr/bin:/bin by default, not /usr/local/bin or other directories where your tools might be installed. Solutions: (1) Use full absolute paths in your cron command: instead of python3 script.py, use /usr/bin/python3 /home/user/script.py. (2) Set PATH at the top of your crontab: PATH=/usr/local/bin:/usr/bin:/bin. (3) Use a wrapper shell script that sources your profile: #!/bin/bash then source ~/.bashrc then your commands. Always test cron scripts with the same limited environment by running: env -i HOME=/home/user bash --noprofile --norc -c "your_command".CRON_TZ=UTC line to the crontab (recommended for servers). Avoid scheduling jobs at 2:00 AM or 2:30 AM when DST transitions typically occur. On Linux with systemd, use systemd timers instead of cron for more predictable DST handling (OnCalendar= in timer units uses wallclock time correctly).systemctl list-timers to see active timers. GitHub Actions scheduled workflows: use cron syntax in on.schedule for CI/CD tasks. AWS EventBridge: managed cron for AWS Lambdas and other services. Google Cloud Scheduler: fully managed cron service for GCP. Celery Beat (Python): task queue with cron-like scheduling. node-cron or cron npm package: in-process scheduling for Node.js. Kubernetes CronJobs: run containerized jobs on a cron schedule. Traditional cron remains the standard on Linux servers for simple tasks due to its zero-dependency, always-available nature.* * * * *), verify it works, then change to the actual schedule. (2) Use run-parts --test /etc/cron.daily to test what would run without executing. (3) Temporarily set the system clock forward using date -s in a test environment. (4) Use the fcron or mcron utilities which offer dry-run modes. (5) For AWS EventBridge, use the "Test" feature in the console. (6) For systemd timers, use systemd-analyze calendar "Mon *-*-* 09:00:00" to see next trigger times. Always redirect output to a log file (>> /tmp/crontest.log 2>&1) during testing so you can see errors.0 0 * * 0 and 0 0 * * 7 are the same schedule. Quartz and AWS count differently: 1 is Sunday and 7 is Saturday, so copy day numbers between systems with care or use the three letter names.0 23 28-31 * * [ "$(date -d tomorrow +\%d)" = 01 ] && /path/to/job. The % must be escaped in a crontab. Quartz and AWS support it directly with L, as in 0 0 12 L * ?.