Skip to main content

cron-parser-py

Cron expression parser with human-readable descriptions and next-run calculation.

Pure Python · Zero dependencies · Python 3.9+

from cron_parser_py import CronParser

expr = CronParser.parse("0 9 * * MON-FRI")
print(expr.description())   # At 9:00 AM, Monday through Friday
print(expr.next_run())       # 2024-01-15 09:00:00
print(expr.next_runs(3))     # [datetime, datetime, datetime]

Installation

pip install cron-parser-py

Features

Capability Details
5-field standard cron MIN HOUR DOM MON DOW
6-field (with seconds) SEC MIN HOUR DOM MON DOW
7-field (with year) SEC MIN HOUR DOM MON DOW YEAR
Predefined macros @yearly, @monthly, @weekly, @daily, @hourly, @reboot
Special characters * / , - ? L W #
Name aliases JAN–DEC, SUN–SAT (case-insensitive)
Human descriptions Natural English for any expression
Next / previous run Forward and backward time search
is_due check Determine if an expression fires right now
Validation Detailed error messages with field/value context

Quick start

Module-level helpers

import cron_parser_py as cron

# Human-readable description
cron.describe("*/5 * * * *")          # "Every 5 minutes"
cron.describe("0 9 * * MON-FRI")      # "At 9:00 AM, Monday through Friday"
cron.describe("0 0 1 1 *")            # "At midnight, on the 1st, in January"

# Validate without raising
cron.is_valid("0 9 * * MON-FRI")      # True
cron.is_valid("99 9 * * *")           # False

# Next run time
cron.next_run("0 * * * *")            # next top-of-hour datetime

# Multiple next runs
cron.next_runs("*/15 * * * *", 5)     # list of 5 datetimes

# Previous run
cron.previous_run("0 0 * * *")        # most recent midnight

# Is due right now?
cron.is_due("* * * * *")              # True (every minute)

CronExpression object

from cron_parser_py import CronParser

expr = CronParser.parse("30 8 * * 1-5")

expr.description()           # "At 8:30 AM, Monday through Friday"
expr.next_run()              # next scheduled datetime
expr.next_runs(count=10)     # list of next 10 datetimes
expr.previous_run()          # most recent past run
expr.is_due()                # True/False right now
str(expr)                    # "30 8 * * 1-5"

Supported syntax

Field positions

Standard 5-field:

┌──────── minute        (0–59)
│ ┌────── hour          (0–23)
│ │ ┌──── day-of-month  (1–31)
│ │ │ ┌── month         (1–12)
│ │ │ │ ┌ day-of-week   (0–7, 0 and 7 = Sunday)
* * * * *

6-field (add seconds at the front):

┌──────────── second       (0–59)
│ ┌────────── minute       (0–59)
│ │ ┌──────── hour         (0–23)
│ │ │ ┌────── day-of-month (1–31)
│ │ │ │ ┌──── month        (1–12)
│ │ │ │ │ ┌── day-of-week  (0–6)
* * * * * *

Special characters

Character Meaning Example
* every value * * * * * — every minute
? any (day fields only) 0 0 ? * 1 — every Monday
/ step */15 * * * * — every 15 min
- range MON-FRI
, list 1,15 * * * — 1st and 15th
L last L in DOM — last day of month
W nearest weekday 15W — nearest weekday to 15th
LW last weekday last weekday of month
# Nth weekday 5#2 — second Friday
nL last Nth weekday 5L — last Friday

Month and weekday names

JAN FEB MAR APR MAY JUN JUL AUG SEP OCT NOV DEC
SUN MON TUE WED THU FRI SAT

Names are case-insensitive and can be used in ranges: MON-FRI.

Predefined macros

Macro Equivalent Description
@yearly / @annually 0 0 1 1 * Once a year, on Jan 1st at midnight
@monthly 0 0 1 * * Once a month, on the 1st at midnight
@weekly 0 0 * * 0 Once a week, on Sunday at midnight
@daily / @midnight 0 0 * * * Every day at midnight
@hourly 0 * * * * Every hour
@reboot — At system startup

API Reference

CronParser

CronParser.parse(expression: str) -> CronExpression

Parse a cron expression string. Raises CronParseError on failure.

CronParser.is_valid(expression: str) -> bool

Return True if the expression is parseable without errors.


CronExpression

Method Returns Description
.description() str Human-readable English description
.next_run(from_time=None) datetime Next run after from_time (default: now)
.next_runs(count=5, from_time=None) list[datetime] Next N run times
.previous_run(from_time=None) datetime Most recent run before from_time
.is_due(at_time=None, tolerance_seconds=0) bool True if expression fires now
str(expr) str Original expression string

CronScheduler

from cron_parser_py import CronParser, CronScheduler

expr = CronParser.parse("0 9 * * *")

CronScheduler.next_run(expr)
CronScheduler.next_runs(expr, count=10)
CronScheduler.previous_run(expr)
CronScheduler.is_due(expr, tolerance_seconds=30)
CronScheduler.time_until_next_run(expr)   # → timedelta

CronValidator

from cron_parser_py import CronParser, CronValidator

expr = CronParser.parse("0 0 30 2 *")

errors = CronValidator.validate(expr, strict=True)
# ["The combination of month(s) and day(s) can never produce a valid date ..."]

CronValidator.assert_valid(expr, strict=True)   # raises CronValidationError

warnings = CronValidator.get_warnings(expr)

CronDescriptor

from cron_parser_py import CronParser, CronDescriptor

expr = CronParser.parse("0 9 * * MON-FRI")
CronDescriptor.describe(expr)   # "At 9:00 AM, Monday through Friday"

# Describe a single field
from cron_parser_py import FieldType
from cron_parser_py.parser import parse_field
field = parse_field("MON-FRI", FieldType.DAY_OF_WEEK)
CronDescriptor.describe_field(field)   # "Monday through Friday"

Exceptions

from cron_parser_py import (
    CronParseError,       # base class
    CronValidationError,  # invalid expression structure
    CronFieldError,       # invalid value in a specific field
    CronScheduleError,    # cannot calculate run time
)

Examples

from datetime import datetime
import cron_parser_py as cron

# -- Descriptions --
cron.describe("* * * * *")            # "Every minute"
cron.describe("*/5 * * * *")          # "Every 5 minutes"
cron.describe("0 * * * *")            # "Every hour"
cron.describe("0 */2 * * *")          # "Every 2 hours"
cron.describe("0 9 * * *")            # "At 9:00 AM"
cron.describe("30 14 * * *")          # "At 2:30 PM"
cron.describe("0 9,17 * * *")         # "At 9:00 AM and 5:00 PM"
cron.describe("0 9 * * 1-5")          # "At 9:00 AM, Monday through Friday"
cron.describe("0 9 * * 1,3,5")        # "At 9:00 AM, on Monday, Wednesday, and Friday"
cron.describe("0 0 1 * *")            # "At midnight, on the 1st"
cron.describe("0 0 L * *")            # "At midnight, on the last day of the month"
cron.describe("0 0 ? * 5#2")          # "At midnight, on the second Friday of the month"
cron.describe("0 0 1 1 *")            # "At midnight, on the 1st, in January"
cron.describe("@weekly")              # "Weekly, at midnight on Sunday"

# -- Scheduling --
ref = datetime(2024, 6, 10, 8, 0)     # Monday 08:00

nxt = cron.next_run("0 9 * * MON-FRI", ref)
# datetime(2024, 6, 10, 9, 0)  — same day at 09:00

runs = cron.next_runs("*/30 8-18 * * 1-5", count=4, from_time=ref)
# Four 30-minute slots on weekdays between 08:00 and 18:00

prev = cron.previous_run("0 0 * * *", ref)
# datetime(2024, 6, 10, 0, 0)  — midnight that day

td = cron.parse("0 9 * * *").next_run(ref) - ref
print(td)   # 1:00:00  (1 hour)

License

MIT © Vladyslav Zaiets

Metadata

Release files for cron-parser-py 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for cron-parser-py 1.0.0
File Size Uploaded
cron_parser_py-1.0.0.tar.gz 17.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for cron-parser-py 1.0.0
File Interpreter ABI Platform
cron_parser_py-1.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 38.6 kB

Release files / cron_parser_py-1.0.0.tar.gz

Download URL cron_parser_py-1.0.0.tar.gz
Size 17.1 kB
Tags Source
SHA-256 checksum
How to use checksums
f6627618cb0588be2b0e7ad3b4739b3473bc54ae799a7b2fc2215c718e8b84ec
BLAKE2b-256 checksum
How to use checksums
39741603da497dd7bc3cfedff7e98e70f1d515b30609eaac826526ab95ed9cb0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.3

Release files / cron_parser_py-1.0.0-py3-none-any.whl

Download URL cron_parser_py-1.0.0-py3-none-any.whl
Size 21.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
583443bca6cb2d38b2eed07e9c34da7bea55f44de50e9eb0f5e4d83eeb3e2121
BLAKE2b-256 checksum
How to use checksums
2a79534f953ae81a0bc06a1b9d59e42d3b37de5f626e5665a8804e473186fe1c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.3

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page