NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
crates.io · #3438 most downloaded on crates.io
Fully-featured, lightweight, and efficient Rust library designed for parsing and evaluating cron patterns
Last release 5 days ago
02 Oct 2026
Release timing varies
gaps range from 8 days to 10 months
Some releases are documented
notes for 12 of 29 stable releases
2 versions withdrawn
withdrawn after publishing
3 years old
31 releases · first in 2023
Fix @Weekly with Quartz weekdays by @bensynapse in #57
Full Changelog: v4.0.0...v4.0.1
One column per month.
Breaking Changes & Migration Guide
CronDateTime Trait & Jiff Support: Introduced a backend-agnostic CronDateTime trait by @ion-elgreco (#48), adding an optional, high-performance jiff datetime backend alongside chrono (#49). The chrono backend is now placed behind an optional feature flag (enabled by default).sloppy_ranges mode ([#39](#39)).Eq and Ord implementations for Cron by @CardboardTurkey ([#43](#43)).chrono by @paolobarbolini ([#42](#42)) and isolated it behind a feature flag.simple_demo to use the Jiff backend ([#52](#52)).Version 4.0 introduces architectural upgrades that may require code adjustments. For complete details, consult the official MIGRATION.md guide. Key breaking changes include:
chrono is now an optional feature flag (enabled by default). If your project compiles with default-features = false, you must explicitly add "chrono" or "jiff" to your Cargo.toml.5/5 * * * *) is now rejected by default and requires explicit ranges like 5-59/5 * * * *. You can restore the old lenient behavior by building your parser with .sloppy_ranges(true).CronDateTime trait instead of chrono::TimeZone. Return types match the input type. When type inference is ambiguous (e.g., with multiple backends enabled), a turbofish annotation may be needed:let next = cron
.find_next_occurrence::<chrono::DateTime<chrono::Utc>>(&chrono::Utc::now(), false)
.unwrap();find_occurrence method has been removed from the public API; use find_next_occurrence instead.croner::from_naive function is deprecated; use chrono::TimeZone::from_local_datetime directly.CronIterator<Tz> has been renamed to CronIterator<T>.Full Changelog: v3.0.1...v4.0.0
CronDateTime trait and shared civil-time abstractions.jiff backend, simple_demo_jiff, and backend parity coverage.LW, +, and strict step-syntax validation.chrono backend optional while keeping it enabled by default.sloppy_ranges(true) available for backward compatibility.This is a patch release that fixes a grammatical issue in cron pattern descriptions and updates several dependencies to their latest versions.
This is a patch release that fixes a grammatical issue in cron pattern descriptions and updates several dependencies to their latest versions.
Fixed grammatical errors in human-readable descriptions for patterns with wildcard minutes/seconds and specific hours.
Before:
Cron::from_str("* 0 * * *").unwrap().describe()
// Output: "At of hour 0." ❌After:
Cron::from_str("* 0 * * *").unwrap().describe()
// Output: "Every minute past hour 0." ✅Additional patterns fixed:
* 5 * * * → "Every minute past hour 5."* 0,12 * * * → "Every minute past hour 0 and 12."* 0-5 * * * → "Every minute past hour 0-5."* */2 * * * → "Every minute past of every 2 hours."* * 0 * * * → "Every second past hour 0." (6-field patterns)* * 5 * * * → "Every second past hour 5." (6-field patterns)All dependencies have been updated to their latest compatible versions:
All updates maintain full backwards compatibility.
Thanks to @JosiahParry for reporting issue #35!
Full Changelog: v3.0.0...v3.0.1
* 0 * * * and * * 0 * * *.Version 3.0 is a significant release, introducing powerful new features, major API enhancements for improved safety and flexibility, and important bug
Version 3.0 is a significant release, introducing powerful new features, major API enhancements for improved safety and flexibility, and important bug fixes.
0 30 23 * * FRI 2025-2026 (At 23:30, on Friday, in year 2025 and 2026). This is breaking because 7-part patterns would throw an error in previous versions, but is successfully parsed with the default configuration from 3.0.0. It's possible to emulate the previous behavior by disallowing years through configuration.find_previous_occurrence() method and iter_before() iterator allow for iterating backwards in time from a given point.CronParser has been enhanced with a builder pattern (CronParser::builder()) for a more type-safe and explicit configuration. This allows you to precisely control:
Optional, Required, Disallowed).Optional, Required, Disallowed).dom_and_dow)..describe() method. This feature is also extensible with internationalization support, demonstrated with an initial Swedish translation.Cron and CronPattern now implement common traits including Eq, PartialEq, Ord, PartialOrd, and Hash. This allows Cron instances to be reliably compared, sorted, and used in hash-based collections like HashMap.L, #, and W. Validation logic has been refined to ensure that the ? wildcard is only permitted in the day-of-month and day-of-week fields, improving pattern integrity.W): The W modifier is now correctly constrained within the given month. The search for the closest weekday will no longer incorrectly cross into a previous or subsequent month.From this version on, the initialization of Cron instances has been updated to use a flexible builder pattern, which is more idiomatic to Rust, and provides greater control and type safety.
Previous Method (Before v3.0)
Previously, Cron was typically initialized directly from a string, which used a default parser configuration:
// Parse cron expression
let cron_all = Cron::new("18 * * * 5")
// <options>
.parse()
.expect("Couldn't parse cron string");New Recommended Method (v3.0 and later)
For v3.0 and later, there are two primary ways to construct a Cron object, depending on your needs.
Directly, using default settings: For simple cases that do not require special configuration, the Cron::from_str() method is the most convenient option.
use std::str::FromStr as _;
use croner::Cron;
let cron = Cron::from_str("*/10 * * * *").unwrap();With a configured parser: For custom behavior, the new builder pattern is the recommended approach.
use croner::parser::{CronParser, Seconds};
use croner::Cron;
let parser = CronParser::builder()
.seconds(Seconds::Disallowed) // Example: Only allow 5-part patterns
.dom_and_dow(true) // Example: require both day-of-month and day-of-week to match (Quartz Mode)
.build();
let cron = parser.parse("0 0 1 * MON").expect("Invalid cron pattern");Full Changelog: v2.2.0...v3.0.0
Add optional support for serde by @jakewmeyer in #15
Full Changelog: v2.1.0...v2.2.0
impl Display for Cron and as_str to get the original pattern by @veeshi in #7
Full Changelog: v2.0.8...v2.1.0
Fixes #13 , error when using '7' as Sunday in "Nth occurrence of weekday"
Full Changelog: v2.0.7...v2.0.8
Fixes #12 , panic when passing 0 as weekday when using .with_alernative_weekdays()
Full Changelog: v2.0.6...v2.0.7
Make cron iterator public by @veeshi in #8
feat: added debug derive impl to Cron struct by @willmalcs in #5
Full Changelog: v2.0.4...v2.0.5
This release contains a minor update, exposing the errors module to the public interface.
This release contains a minor update, exposing the errors module to the public interface.
Full Changelog: v2.0.3...v2.0.4
Maintenance release focusing mainly on documentation updates and additional test cases.
Maintenance release focusing mainly on documentation updates and additional test cases.
Full Changelog: v2.0.2...v2.0.3
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Your coding agent can read these notes before it upgrades. Set up the MCP server →