The project is in a healthy, maintained state
Parse standard 5-field cron expressions and calculate next/previous occurrences, match times against patterns, and generate human-readable descriptions.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies
 Project Readme

philiprehberger-cron_parser

Tests Gem Version Last updated

Cron expression parser for calculating next and previous occurrences

Requirements

  • Ruby >= 3.1

Installation

Add to your Gemfile:

gem "philiprehberger-cron_parser"

Or install directly:

gem install philiprehberger-cron_parser

Usage

require "philiprehberger/cron_parser"

cron = Philiprehberger::CronParser.new('0 9 * * 1-5')
cron.next(from: Time.now)   # => next weekday at 9:00 AM
cron.prev(from: Time.now)   # => previous weekday at 9:00 AM

Next Occurrences

cron = Philiprehberger::CronParser.new('*/15 * * * *')
cron.next_n(5, from: Time.now)  # => next 5 quarter-hour times

Matching

cron = Philiprehberger::CronParser.new('0 9 * * *')
cron.matches?(Time.new(2026, 3, 22, 9, 0, 0))  # => true
cron.matches?(Time.new(2026, 3, 22, 10, 0, 0)) # => false

Human-Readable Description

cron = Philiprehberger::CronParser.new('30 9 * * 1-5')
cron.human_readable  # => "at minute 30, at hour 9, on weekday 1,2,3,4,5"

Named Months and Weekdays

Use named months (JAN-DEC) and weekdays (SUN-SAT) in cron expressions. Names are case-insensitive and work in ranges and lists.

Philiprehberger::CronParser.new('0 0 1 JAN *')         # first of January
Philiprehberger::CronParser.new('0 0 1 JAN-MAR *')     # first of Jan-Mar
Philiprehberger::CronParser.new('0 0 * * MON')         # every Monday
Philiprehberger::CronParser.new('0 0 * * MON-FRI')     # weekdays
Philiprehberger::CronParser.new('0 0 * * MON,WED,FRI') # specific days
Philiprehberger::CronParser.new('0 0 * * 1,WED,5')     # mixed numeric and named

Named Aliases

Standard crontab aliases are supported (case-insensitive):

Philiprehberger::CronParser.new('@hourly')    # => 0 * * * *
Philiprehberger::CronParser.new('@daily')     # => 0 0 * * *
Philiprehberger::CronParser.new('@midnight')  # alias for @daily
Philiprehberger::CronParser.new('@weekly')    # => 0 0 * * 0
Philiprehberger::CronParser.new('@monthly')   # => 0 0 1 * *
Philiprehberger::CronParser.new('@yearly')    # => 0 0 1 1 *
Philiprehberger::CronParser.new('@annually')  # alias for @yearly

Validation

Philiprehberger::CronParser.valid?('*/5 * * * *')  # => true
Philiprehberger::CronParser.valid?('60 * * * *')   # => false

result = Philiprehberger::CronParser.validate('60 25 * * *')
result[:valid]   # => false
result[:errors]  # => ["minute field: Value 60 out of range (0-59)", "hour field: Value 25 out of range (0-23)"]

Supported Syntax

Standard 5-field cron expressions (minute hour day month weekday):

Philiprehberger::CronParser.new('* * * * *')       # every minute
Philiprehberger::CronParser.new('*/5 * * * *')     # every 5 minutes
Philiprehberger::CronParser.new('0 9-17 * * *')    # hourly 9am-5pm
Philiprehberger::CronParser.new('0 9,12,17 * * *') # specific hours
Philiprehberger::CronParser.new('0 0 1 * *')       # first of month
Philiprehberger::CronParser.new('0 0 1 JAN-MAR *') # named months
Philiprehberger::CronParser.new('0 9 * * MON-FRI') # named weekdays

API

Method Description
CronParser.new(expr) Parse a 5-field cron expression
CronParser.valid?(expr) Check if expression is valid (returns boolean)
CronParser.validate(expr) Validate with structured field-level errors
Expression#next(from:) Calculate the next matching time
Expression#prev(from:) Calculate the previous matching time
Expression#next_n(n, from:) Calculate the next N matching times
Expression#matches?(time) Check if a time matches the expression
Expression#human_readable Human-readable description of the expression
Expression#description Alias for human_readable

Development

bundle install
bundle exec rspec
bundle exec rubocop

Support

If you find this project useful:

Star the repo

🐛 Report issues

💡 Suggest features

❤️ Sponsor development

🌐 All Open Source Projects

💻 GitHub Profile

🔗 LinkedIn Profile

License

MIT