Cron Expression Parser
Parse cron expressions into human-readable descriptions and preview next run times
Cron expression
minute hour day(month) month day(week)
Human-readable description
At 9:00 AM, Mon, Tue, Wed, Thu, Fri
Field breakdown
Minute
0
0β59
Hour
9
0β23
Day (month)
*
1β31
Month
*
1β12
Day (week)
1-5
0β6
Next 10 scheduled runs
What Is Cron Expression Parsing?
A cron expression is a string of five fields separated by spaces that defines a recurring schedule. The format originated in the Unix cron daemon, first written by Ken Thompson for Version 7 Unix in 1979. Each field represents a time unit: minute, hour, day of the month, month, and day of the week. Parsing a cron expression means converting this compact notation into a human-readable description and a concrete list of upcoming execution times.
The standard five-field format is used by crontab on Linux and macOS, by CI/CD platforms like GitHub Actions and GitLab CI, by cloud schedulers in AWS (EventBridge), Google Cloud Scheduler, and Azure Functions, and by job-scheduling libraries in every major programming language. Some systems extend the format to six or seven fields by adding a seconds field or a year field, but the five-field layout defined by POSIX remains the baseline that all implementations share.
Parsing cron expressions by hand is error-prone. The interaction between fields creates non-obvious schedules: 0 9 1-7 * 1 does not mean 'every Monday in the first week' but rather 'the 1st through 7th of every month OR any Monday.' A cron parser eliminates this ambiguity by expanding each field, applying the combination rules, and producing the actual timestamps when the job will fire.
Why Use This Cron Parser?
Reading a cron expression like 30 */6 1,15 * * from a config file and knowing exactly when it fires requires mental arithmetic across five fields. This parser does that work instantly.
Cron Parser Use Cases
Cron Expression Syntax Reference
A standard cron expression has five space-separated fields. Each field accepts integers, wildcards, ranges, lists, and step values. The table below shows the allowed range and operators for each field.
| Field | Range | Operators | Description |
|---|---|---|---|
| Minute | 0β59 | * , - / | Minute within the hour |
| Hour | 0β23 | * , - / | Hour of the day (24-hour) |
| Day (month) | 1β31 | * , - / | Day of the month |
| Month | 1β12 | * , - / | Month of the year (or JANβDEC) |
| Day (week) | 0β6 | * , - / | Day of the week (0 = Sunday, or SUNβSAT) |
Four special characters control how values are matched within each field:
| Char | Name | Behavior |
|---|---|---|
| * | Wildcard | Matches every possible value in the field. * in the minute field means "every minute." |
| , | List | Separates individual values. 1,15 in the day field means "the 1st and 15th." |
| - | Range | Defines an inclusive range. 1-5 in the day-of-week field means "Monday through Friday." |
| / | Step | Defines an interval. */10 in the minute field means "every 10 minutes." 5/15 means "5, 20, 35, 50." |
Here are common cron expressions that cover most scheduling needs:
| Expression | Schedule |
|---|---|
| * * * * * | Every minute |
| 0 * * * * | Every hour (at minute 0) |
| */15 * * * * | Every 15 minutes |
| 0 9 * * * | Every day at 9:00 AM |
| 0 9 * * 1-5 | Weekdays at 9:00 AM |
| 30 2 * * 0 | Every Sunday at 2:30 AM |
| 0 0 1 * * | First day of every month at midnight |
| 0 0 * * 1 | Every Monday at midnight |
| 0 0 1 1 * | January 1st at midnight (yearly) |
| 0 */6 * * * | Every 6 hours |
| 5,35 * * * * | At minute 5 and 35 of every hour |
| 0 9-17 * * 1-5 | Every hour from 9 AM to 5 PM, weekdays |
Code Examples
How to parse cron expressions and calculate next run times in popular languages:
import cronstrue from 'cronstrue';
// Parse cron to human-readable text
cronstrue.toString('0 9 * * 1-5');
// β "At 09:00 AM, Monday through Friday"
cronstrue.toString('*/15 * * * *');
// β "Every 15 minutes"
// Validate with cron-parser and get next run times
import { parseExpression } from 'cron-parser';
const interval = parseExpression('30 2 * * 0');
console.log(interval.next().toISOString());
// β next Sunday at 02:30 UTC
// Iterate over the next 5 runs
for (let i = 0; i < 5; i++) {
console.log(interval.next().toString());
}from crontab import CronTab
from croniter import croniter
from datetime import datetime
# Parse and describe a cron expression
cron = CronTab('0 9 * * 1-5')
print(cron.next(default_utc=True))
# β seconds until next run
# Get the next 5 run times with croniter
base = datetime.now()
cron_iter = croniter('0 9 * * 1-5', base)
for _ in range(5):
print(cron_iter.get_next(datetime))
# β next 5 weekday 09:00 timestamps
# Check if a specific time matches
print(croniter.match('*/15 * * * *', datetime(2026, 3, 25, 10, 30)))
# β True (minute 30 is divisible by 15)package main
import (
"fmt"
"time"
"github.com/robfig/cron/v3"
)
func main() {
// Parse a standard 5-field cron expression
parser := cron.NewParser(cron.Minute | cron.Hour | cron.Dom | cron.Month | cron.Dow)
schedule, err := parser.Parse("0 9 * * 1-5")
if err != nil {
panic(err)
}
// Calculate the next 5 run times
now := time.Now()
for i := 0; i < 5; i++ {
now = schedule.Next(now)
fmt.Println(now)
}
// β next 5 weekday 09:00 timestamps
}# List current user's cron jobs crontab -l # Edit cron jobs interactively crontab -e # Add a job: run backup.sh every day at 2:30 AM # (append to crontab via pipe) (crontab -l 2>/dev/null; echo "30 2 * * * /home/user/backup.sh") | crontab - # Check syntax with a dry-run parse (requires cronie or busybox) # The system will reject invalid expressions when saving # View cron logs on systemd-based Linux journalctl -u cron --since "1 hour ago"