Skip to content

Cronspell Python Package / CLI Tool

Chronometry Spelled Out

Github Pages

Details Tests License - MIT
Features linting - Ruff types - mypy test - pytest Pre-Commit docs - mkdocs

Date-expression domain specific language (DSL) parsing. A neat way to express things like "First Saturday of any year", or "3rd thursdays each month" and such.

Status

CronSpell is currently in Beta. While it is considered well tested and stable for most use cases, there may still be some edge cases and bugs that need to be addressed. The maintainer encourages users to try it out and provide feedback to help improving the library.

Your contributions and bug reports are highly appreciated.

Features

Cronspell is heavily inspired by Grafana's relative Date picker user interface. It was designed for the cases when configuration is needed to reflect irregular date-distances.

It offers a domain specific language to express relative dates and schedules. This way, any kind of date relation that humans easily understand can be conveyed.

Python Usage

Installation:

pip install cronspell

Import:

from cronspell import Cronspell, parse

Cli Usage

Installation:

pip install 'cronspell[cli]'

List available commands:

cronspell --help

Syntax Specification

Cronspell works by iteratively processing anything that matches its language specification.

Based on the starting point Anchor=now[UTC] zero or more subsequent date math directives 0..*{DateMath} affect the outcome.

The most simple although pointles example of a valid model is a zero-withd string due tho these permissive constraints.

Example Expressions

latest Saturday of past month:

/month -1 day /sat

Calendar Week divisible by 3 or 10:

{@cw 3, @cw 10}
Parser Internals — click to toggle visibility
Legend
Entity Pattern Examples
ISODate
\d{4}-\d{2}-\d{2}\S*
1979-01-01T00:00:00+00:00
Now
now
now
now[Europe/Berlin]
CalendarWeekModulo
(%|@)\s*(CW|Cw|cw)
@cw
YearModulo
(%|@)\s*(Y|y)(ears?)?
@y
MonthModulo
(%|@)\s*([Mm])(onths?)?
@m
Y
([Yy]ears?|Y\b)
Y
Years
Year
year
m
(?!mon\b)([mM]onths?|m\b)
m
Months
Month
month
W
\b([wW]eeks?|W)\b
W
Weeks
Week
week
d
([dD]ays?|d\b)
d
Days
Day
day
M
([mM]inutes?|M\b|[mM]in\b)
M
Minutes
Minute
minute
H
([hH]ours?|H\b|[Hh]rs)
H
Hours
Hour
hour
S
(?!sat$)([sS]econds?|S\b|[sS]ec\b)
S
Seconds
Second
second
Mon
\b[mM]on(?:day)?\b
Mon
Monday
monday
Tue
\b[tT]ue(?:sday)?\b
Tue
Tuesday
tuesday
Wed
\b[wW]ed(?:nesday)?\b
Wed
Wednesday
wednesday
Thu
\b[tT]hu(?:rsday)?\b
Thu
Thursday
thursday
Fri
\b[fF]ri(?:day)?\b
Fri
Friday
friday
Sat
\b[sS]at(?:urday)?\b
Sat
Saturday
saturday
Sun
\b[sS]un(?:day)?\b
Sun
Sunday
sunday
Jan
\b[jJ]an(?:uary)?\b
Jan
January
january
Feb
\b[fF]eb(?:ruary)?\b
Feb
February
february
Mar
\b[mM]ar(?:ch)?\b
Mar
March
march
Apr
\b[aA]pr(?:il)?\b
Apr
April
april
May
\b[mM]ay\b
May
May
may
Jun
\b[jJ]une?\b
Jun
June
june
Jul
\b[jJ]uly?\b
Jul
July
july
Aug
\b[aA]ug(?:ust)?\b
Aug
August
august
Sep
\b[sS]ep(?:tember)?\b
Sep
September
september
Oct
\b[oO]ct(?:ober)?\b
Oct
October
october
Nov
\b[nN]ov(?:ember)?\b
Nov
November
november
Dec
\b[dD]ec(?:ember)?\b
Dec
December
december
Comment
\/\*(.|\n)*?\*\/|\/\/.*?$
/*
    multi-line
    block
    comment
*/
/* inline comment */
/* inline comment */

pre-commit hook

This package comes with a pre-commit hook that allows for automated preflight checks on yaml files serving as sources for cronspell expressions.

Put this in your .pre-commit-config.yaml and adjust according to your needs:

repos:
  - repo: https://github.com/iilei/cronspell
    rev: c2b316f53c536e808353d2b30b97d1660c267d4b   # v0.4.1
    hooks:
      - id: cronspell
        files: .*\/cfg\.ya?ml$
        args: ["--yamlpath", "/*/*date*" ]

Credits

  • Domain-Specific-Language Parser: TextX
  • This package was created with The Hatchlor project template.

Documentation for specific MAJOR.MINOR versions can be chosen by using the dropdown on the top of every page. The dev version reflects changes that have not yet been released. Shortcuts can be used for navigation, i.e. ,/p and ./n for previous and next page, respectively, as well as //s for searching.