Skip to main content

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

Project description

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

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cron_parser_py-1.0.0.tar.gz (17.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

cron_parser_py-1.0.0-py3-none-any.whl (21.6 kB view details)

Uploaded Python 3

File details

Details for the file cron_parser_py-1.0.0.tar.gz.

File metadata

  • Download URL: cron_parser_py-1.0.0.tar.gz
  • Upload date:
  • Size: 17.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for cron_parser_py-1.0.0.tar.gz
Algorithm Hash digest
SHA256 f6627618cb0588be2b0e7ad3b4739b3473bc54ae799a7b2fc2215c718e8b84ec
MD5 25ea785cf8b0987081e7990656789866
BLAKE2b-256 39741603da497dd7bc3cfedff7e98e70f1d515b30609eaac826526ab95ed9cb0

See more details on using hashes here.

File details

Details for the file cron_parser_py-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: cron_parser_py-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 21.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for cron_parser_py-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 583443bca6cb2d38b2eed07e9c34da7bea55f44de50e9eb0f5e4d83eeb3e2121
MD5 03e619b27ab6c4351f2b6a8c5cc6c16c
BLAKE2b-256 2a79534f953ae81a0bc06a1b9d59e42d3b37de5f626e5665a8804e473186fe1c

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page