Cron Expression Builder
cron-expression-builder
Build and validate cron expressions from natural language. Convert between human-readable schedules and cron syntax with next run preview.
SKILL.md
Full skill instructions
Cron Expression Builder
Build, parse, and validate cron expressions with natural language conversion and run time preview.
Features
- Natural Language: Convert descriptions to cron expressions
- Cron Parser: Parse cron to human-readable format
- Validation: Validate cron syntax
- Next Runs: Preview upcoming execution times
- Presets: Common scheduling patterns
- Both Formats: 5-field (standard) and 6-field (with seconds)
Quick Start
from cron_builder import CronBuilder
builder = CronBuilder()
# Build from natural language
cron = builder.from_text("every day at 3:30 PM")
print(cron) # 30 15 * * *
# Parse to human-readable
description = builder.describe("0 */2 * * *")
print(description) # "Every 2 hours"
# Get next run times
runs = builder.next_runs("30 15 * * *", count=5)
for run in runs:
print(run)
CLI Usage
# Build from text
python cron_builder.py --from-text "every monday at 9am"
# Describe a cron expression
python cron_builder.py --describe "0 9 * * 1"
# Validate expression
python cron_builder.py --validate "0 9 * * 1"
# Get next 10 runs
python cron_builder.py --next "0 9 * * 1" --count 10
# List preset schedules
python cron_builder.py --presets
# Use preset
python cron_builder.py --preset daily_midnight
# Interactive builder
python cron_builder.py --interactive
API Reference
CronBuilder Class
class CronBuilder:
def __init__(self, with_seconds: bool = False)
# Building
def from_text(self, text: str) -> str
def build(self, minute: str = "*", hour: str = "*",
day: str = "*", month: str = "*",
weekday: str = "*") -> str
# Parsing
def describe(self, expression: str) -> str
def parse(self, expression: str) -> dict
# Validation
def validate(self, expression: str) -> dict
def is_valid(self, expression: str) -> bool
# Execution times
def next_runs(self, expression: str, count: int = 5,
from_date: datetime = None) -> list
def matches(self, expression: str, dt: datetime) -> bool
# Presets
def get_preset(self, name: str) -> str
def list_presets(self) -> dict
Cron Expression Format
5-Field Format (Standard)
┌───────────── minute (0-59)
│ ┌───────────── hour (0-23)
│ │ ┌───────────── day of month (1-31)
│ │ │ ┌───────────── month (1-12)
│ │ │ │ ┌───────────── day of week (0-6, Sun=0)
│ │ │ │ │
* * * * *
6-Field Format (With Seconds)
┌───────────── second (0-59)
│ ┌───────────── minute (0-59)
│ │ ┌───────────── hour (0-23)
│ │ │ ┌───────────── day of month (1-31)
│ │ │ │ ┌───────────── month (1-12)
│ │ │ │ │ ┌───────────── day of week (0-6)
│ │ │ │ │ │
* * * * * *
Natural Language Conversion
Supported Patterns
# Time-based
builder.from_text("every minute") # * * * * *
builder.from_text("every 5 minutes") # */5 * * * *
builder.from_text("every hour") # 0 * * * *
builder.from_text("every 2 hours") # 0 */2 * * *
# Daily
builder.from_text("every day at noon") # 0 12 * * *
builder.from_text("daily at 3pm") # 0 15 * * *
builder.from_text("at 3:30 PM every day")# 30 15 * * *
# Weekly
builder.from_text("every monday") # 0 0 * * 1
builder.from_text("weekdays at 9am") # 0 9 * * 1-5
builder.from_text("every friday at 5pm") # 0 17 * * 5
# Monthly
builder.from_text("first of every month")# 0 0 1 * *
builder.from_text("15th of each month") # 0 0 15 * *
builder.from_text("last day of month") # 0 0 L * *
# Special
builder.from_text("every sunday at midnight") # 0 0 * * 0
builder.from_text("twice daily") # 0 0,12 * * *
Presets
Built-in common schedules:
| Preset | Cron | Description |
|---|---|---|
every_minute | * * * * * | Every minute |
every_5_minutes | */5 * * * * | Every 5 minutes |
every_15_minutes | */15 * * * * | Every 15 minutes |
every_30_minutes | */30 * * * * | Every 30 minutes |
hourly | 0 * * * * | Every hour |
daily_midnight | 0 0 * * * | Daily at midnight |
daily_noon | 0 12 * * * | Daily at noon |
weekly_sunday | 0 0 * * 0 | Weekly on Sunday |
weekly_monday | 0 0 * * 1 | Weekly on Monday |
monthly | 0 0 1 * * | First of month |
quarterly | 0 0 1 1,4,7,10 * | First day of quarter |
yearly | 0 0 1 1 * | January 1st |
cron = builder.get_preset("daily_noon")
# "0 12 * * *"
Cron Description
Convert cron to human-readable:
builder.describe("30 15 * * 1-5")
# "At 3:30 PM, Monday through Friday"
builder.describe("0 */6 * * *")
# "Every 6 hours"
builder.describe("0 9 15 * *")
# "At 9:00 AM on day 15 of every month"
Validation
result = builder.validate("0 9 * * 1")
# Returns:
{
"valid": True,
"expression": "0 9 * * 1",
"fields": {
"minute": "0",
"hour": "9",
"day_of_month": "*",
"month": "*",
"day_of_week": "1"
},
"description": "At 9:00 AM, only on Monday"
}
# Invalid expression
result = builder.validate("60 25 * * *")
# Returns:
{
"valid": False,
"error": "Invalid minute: 60 (must be 0-59)"
}
Next Run Times
Preview upcoming executions:
runs = builder.next_runs("0 9 * * 1", count=5)
# Returns:
[
"2024-01-15 09:00:00", # Next Monday
"2024-01-22 09:00:00",
"2024-01-29 09:00:00",
"2024-02-05 09:00:00",
"2024-02-12 09:00:00"
]
Check Specific Time
from datetime import datetime
# Does this cron run at this time?
matches = builder.matches("0 9 * * 1", datetime(2024, 1, 15, 9, 0))
# True (Monday at 9 AM)
Manual Building
Build expression field by field:
# Every Monday at 9:30 AM
cron = builder.build(
minute="30",
hour="9",
day="*",
month="*",
weekday="1"
)
# "30 9 * * 1"
# Every 15 minutes during business hours on weekdays
cron = builder.build(
minute="*/15",
hour="9-17",
day="*",
month="*",
weekday="1-5"
)
# "*/15 9-17 * * 1-5"
Example Workflows
Schedule Builder
builder = CronBuilder()
# Create schedule from user input
schedule_text = "every weekday at 8:30 AM"
cron = builder.from_text(schedule_text)
# Validate and preview
if builder.is_valid(cron):
print(f"Cron: {cron}")
print(f"Description: {builder.describe(cron)}")
print("\nNext 5 runs:")
for run in builder.next_runs(cron, count=5):
print(f" {run}")
Job Scheduler Integration
# Define schedules for different jobs
jobs = {
"backup": builder.get_preset("daily_midnight"),
"reports": builder.from_text("every monday at 8am"),
"cleanup": builder.from_text("first sunday of month at 2am")
}
for job_name, cron in jobs.items():
print(f"{job_name}: {cron}")
print(f" Next run: {builder.next_runs(cron, count=1)[0]}")
Dependencies
- croniter>=1.4.0 (for next run calculations)
