askill
cron-expressions

cron-expressionsSafety 95Repository

Generate native cron expression parsing, matching, and scheduling — recurring time patterns, crontab semantics, next-occurrence calculation — from a verified TypeScript reference

1 stars
1.2k downloads
Updated 2/5/2026

Package Files

Loading files...
SKILL.md

cron-expressions

Parse, validate, match, and iterate over standard cron expressions as pure functions. Supports 5-field cron format with Vixie extensions (L, W, #) and correct semantics for every edge case that libraries disagree on.

Design principles

  • Pure functions only — every function takes explicit inputs; no global state.
  • UTC throughout — all datetime math uses UTC. No timezone handling.
  • Vixie cron semantics — follows Vixie cron 4.1 conventions, documented with provenance for every design decision.
  • Clarity over performance — reference code prioritizes readability. Minute-scanning is used for next-occurrence rather than optimized field-walking.

Input

$ARGUMENTS accepts:

  • help: Interactive guide to choosing the right nodes and language for your use case
  • Nodes: space-separated node names to generate (or all for the full library)
  • --lang <language>: target language (default: typescript). Supported: python, rust, go, typescript

Examples:

  • help — walk through choosing which nodes you need
  • matcher — generate matcher + dependencies in TypeScript
  • next-occurrence --lang python — generate next-occurrence + dependencies in Python
  • all --lang rust — generate the full library in Rust

Handling help

When $ARGUMENTS is help, read HELP.md and use it to guide the user through node and language selection. The help guide contains a decision tree and common use-case recipes. Walk through it interactively, asking the user about their requirements, then recommend specific nodes and a target language.

Node Graph

cron-types ────────────────┬──► tokenizer ──► parser ──┐
  (leaf)                   │       (leaf)    (internal) │
                           │                           │
field-range ───────────────┤──────────────► matcher ────┤
  (leaf)                   │               (internal)   │
                           │                   │        │
                           │          next-occurrence ──┤
                           │             (internal)     │
                           │                   │        │
                           │              iterator ─────┤
                           │             (internal)     │
                           │                            │
                           └───────────► cron-schedule ─┘
                                           (root)

Nodes

NodeTypeDepends OnDescription
cron-typesleafCronFieldEntry, CronField, CronExpression type definitions and factories
field-rangeleafValid ranges per field, month/day-of-week aliases, last-day-of-month calculation
tokenizerleafSplits cron string into 5 field strings
parserinternalcron-types, field-range, tokenizerParses field strings into CronExpression AST
matcherinternalcron-types, field-rangeTests whether a UTC datetime matches a CronExpression
next-occurrenceinternalcron-types, matcherFinds next/previous datetime matching a CronExpression
iteratorinternalcron-types, next-occurrenceLazy iteration over matching datetimes; nextN convenience
cron-schedulerootcron-types, parser, matcher, next-occurrence, iteratorPublic API: parse, match, next, prev, nextN, iterate

Subset Extraction

  • Parse only: cron-types + field-range + tokenizer + parser
  • Match a datetime: cron-types + field-range + matcher (+ parser if starting from string)
  • Find next occurrence: add next-occurrence to the match subset
  • Iterate over occurrences: add iterator to the next-occurrence subset
  • Full library: all 8 nodes via cron-schedule

Key Design Decisions

Day-of-month / day-of-week interaction (THE critical decision)

@provenance Vixie cron 4.1, crontab(5) man page

When both day-of-month and day-of-week are restricted (not wildcard), the match uses union (OR) — matching either field is sufficient. This is the Vixie cron convention, which differs from what most people expect (intersection/AND).

ExpressionMatchesRule
0 0 15 * 515th of any month OR any FridayUnion (both restricted)
0 0 15 * *15th of any monthOnly DoM restricted
0 0 * * 5Every FridayOnly DoW restricted

Sunday representation

@provenance POSIX.1-2017 crontab(5), Vixie cron 4.1

InputNormalizedNotes
00 (Sunday)POSIX standard
70 (Sunday)Vixie extension — both 0 and 7 mean Sunday
SUN0 (Sunday)Case-insensitive alias

Field modifiers

ModifierValid InMeaningSource
LdayOfMonthLast day of monthQuartz, spring-cron
nLdayOfWeekLast nth-day of month (e.g., 5L = last Friday)Quartz
n#ndayOfWeekNth weekday of month (e.g., 5#3 = third Friday)Quartz
nWdayOfMonthNearest weekday to nth day (never crosses month boundary)Quartz

Nearest weekday (W) boundary rules

@provenance Quartz scheduler W modifier semantics

ScenarioResolution
Target is a weekdayUse target as-is
Target is Saturday, not 1stUse Friday (target - 1)
1st is SaturdayUse Monday the 3rd (can't go to previous month)
Target is Sunday, not last dayUse Monday (target + 1)
Last day is SundayUse Friday (target - 2, can't go to next month)

Process

  1. If $ARGUMENTS is help, read HELP.md and guide the user interactively
  2. Read this file for the node graph and design decisions
  3. For each requested node (in dependency order), read nodes/<name>/spec.md
  4. Read nodes/<name>/to-<lang>.md for target-language translation hints
  5. Generate implementation + tests
  6. If the spec is ambiguous, consult reference/src/<name>.ts (track what you consulted and why)
  7. Run tests — all must pass before proceeding to the next node

Error Handling

  • tokenize throws on empty/whitespace input or wrong field count (not 5)
  • parseCron throws on: out-of-range values, invalid step values (0 or negative), unrecognized tokens, invalid nth values (#0 or #6+)
  • matchesCron is a total function (no error cases)
  • nextOccurrence / prevOccurrence return null if no match within ~1 year
  • cronSchedule throws on invalid expressions (delegates to parseCron)

Reference

The TypeScript reference implementation is in reference/src/. It is the authoritative source — consult it when specs are ambiguous, but prefer the spec and translation hints as primary sources.

All reference code has 100% line and function coverage via bun test --coverage.

Install

Download ZIP
Requires askill CLI v1.0+

AI Quality Score

83/100Analyzed 2/24/2026

High-quality reference-style skill for generating cron expression parsing code. Excellent structure with node graph, detailed design decisions with provenance, and multi-language support. Slightly penalized for relying on external files not included in the skill document itself. Good clarity and completeness, with strong reusability potential beyond the original repo."

95
90
85
85
75

Metadata

Licenseunknown
Version-
Updated2/5/2026
Publishercaryden

Tags

apitesting