Skip to content
CAI
Software that uses CAICheck a score

alonsodomin/cron4s

55.1

Adequate · 20 September 2026

6.9k

lines of production code

Scala

primary language

1

measurement over time

CAI band scale
CAI lens gauges

What this system is

This system is a cross-platform Scala library for parsing, validating, and evaluating cron expressions. It provides a type-safe API to match schedules against date-time instances, supporting Java 8 java.time, Joda-Time, and JavaScript Date via dedicated integration modules. The library is designed for high performance and broad compatibility, running on JVM, JavaScript, and Native platforms across Scala 2.12, 2.13, and 3.

How it got here

2015–2017 — Build modernization and test expansion

12 changes.

The project underwent a significant infrastructure overhaul, migrating the build system to SBT 1.12 and adding support for Scala 3 and cross-compilation targets. This period also involved removing the initial cron expression model to prepare for a refactored architecture while extensively expanding test coverage, including property-based tests, benchmarks, and validation suites for the new AST nodes and datetime integrations.

2019 — Core library foundation and multi-platform integration

14 changes.

This period established the foundational architecture of the cron4s library, introducing core parsing logic, abstract syntax trees, and type-class-based abstractions for date-time evaluation. It simultaneously expanded platform support by adding integration modules for Java Time, Joda-Time, Moment.js, and Scala Native, while ensuring cross-compilation compatibility with Scala 2.12.

2023–2025 — Scala 3 migration and parser modernization

7 changes.

The project introduced Scala 3 cross-compilation support for core logic while promoting the Atto parser as the new default, replacing the deprecated parser-combinator implementation. This period focused on ensuring parsing consistency across platforms through configurable parser selection and comprehensive cross-platform test coverage.

Features

Add Doobie integration module for storing CronExpr in databases

A new extension module for Doobie has been added, providing implicit Meta, Read, and Write instances for CronExpr. This allows users to store and retrieve cron expressions directly in relational databases via Doobie, mapping them to VARCHAR columns. The implementation validates expressions on read, throwing a SecondaryValidationFailed error if the stored string is not a valid cron expression.

modules/doobie · high confidence

Add Joda-Time integration for cron expressions

The Joda-Time module now provides first-class support for Joda date-time types within cron4s. Users can parse, validate, and manipulate cron expressions using Joda's DateTime, LocalDateTime, LocalDate, and LocalTime classes. This integration exposes implicit instances for equality and string representation, and implements the IsDateTime type class to allow standard cron operations (such as adding time units or retrieving field values) on Joda objects.

modules/joda/src/main · high confidence

Add Moment.js integration for date-time handling

This change introduces a new \momentjs\ module that provides an \IsDateTime\ instance for JavaScript \Date\ objects backed by the Moment.js library. It enables cron expressions to be evaluated against Moment.js dates, supporting all standard cron fields (seconds, minutes, hours, day of month, month, and day of week) for both getting and setting values. The module includes the necessary encoder/decoder-like instance definitions and a comprehensive test suite to verify date-time arithmetic and cron matching behavior with Moment.js.

modules/momentjs · high confidence

Add decline integration for cron expression arguments

Users can now pass cron expressions directly as command-line arguments in applications using the decline library. This change introduces an implicit Argument instance for CronExpr, allowing seamless parsing of cron syntax from CLI inputs, along with corresponding tests to verify correct behavior.

modules/decline · high confidence

Cron4s core library files are newly introduced

The diff shows the initial creation of the core source files for the cron4s library, including definitions for CRON fields (CronField), units (CronUnit), parsing logic (CronImpl, ParserAdapter), error handling (errors.scala), and the main package object. This establishes the foundational types and parsing infrastructure for the library.

modules/core/shared/src/main/scala/cron4s · high confidence

Introduce base abstractions for enumerated ranges and predicates

The library now includes foundational type classes in the \cron4s.base\ package to support expression parsing and evaluation. The new \Enumerated\[A\]\ trait provides utilities for navigating integer ranges, including stepping forward or backward with carry-over logic, and determining min/max values. Additionally, the \Predicate\[A\]\ trait introduces a composable boolean filter interface with support for logical conjunction (\and\/\&&\) and disjunction (\or\/\\|\|\), backed by Cats type classes like \Contravariant\ and \MonoidK\ for algebraic combination of predicates.

modules/core/shared/src/main/scala/cron4s/base · high confidence

Introduce core datetime evaluation and adapter abstractions

The library now provides a structured foundation for evaluating cron expressions against date-time values. This change introduces the \DateTimeCron\ trait, which defines the core API for matching, stepping (finding next/previous occurrences), and extracting ranges for full, time-only, and date-only cron expressions. It also adds the \IsDateTime\ type class, serving as a bridge adapter that allows the library to work with specific date-time libraries by defining how to get, set, and add units to date-time instances. Supporting types include \DateTimeNode\ for field-level operations, \DateTimeUnit\ for time granularity, and \DateTimeError\ for handling unsupported fields or invalid values.

modules/core/shared/src/main/scala/cron4s/datetime · high confidence

Introduction of cron4s syntax and Java Time integration

This change introduces the core syntax DSL for the cron4s library, providing extension methods on cron expressions to check matches, find next/previous occurrences, and inspect field ranges. It also adds a new Java Time integration module that implements the IsDateTime typeclass for standard java.time types (LocalDate, LocalDateTime, ZonedDateTime, etc.), enabling the syntax features to work with Java's date and time API.

modules/core/shared/src/main/scala/cron4s/syntax · high confidence

Scala 3 cross-compilation support for core datetime and expression logic

The core library now compiles on Scala 3 alongside Scala 2, providing parallel implementations in the scala-3 source directory for the datetime stepper, predicate reducer, and expression AST nodes. This enables users to build cron4s against Scala 3 while preserving the existing Scala 2 behavior for scheduling and expression handling.

modules/core/shared/src/main/scala-3 · high confidence

Testkit adds Scala Native support and cross-platform platform detection

The testkit module now supports Scala Native in addition to JVM and JavaScript. This is implemented by adding platform-specific \platform.scala\ files that expose a \Platform\ object with \isJvm\, \isJs\, and \isNative\ flags, allowing the test suite to adjust its behavior (such as property check configuration in \Cron4sLawSuite\) based on the target runtime. The testkit also includes comprehensive property-based testing generators and discipline laws for cron expressions and date-time operations across these platforms.

modules/testkit · high confidence

Removals

Removal of initial cron expression model and constraint system

The initial implementation of the cron expression parsing model has been removed. This includes the deletion of the \CronExpr\ class, the \constraint\ package (containing \Step\, \Range\, and \Group\ constraints), the \field\ package (defining \MinuteField\ and \HourField\), the \unit\ package (defining \CronUnit\ traits and operations for time units like minutes, hours, days, months, and years), and the \value\ package (defining value types such as \IntVal\, \StringVal\, \RangeVal\, and \FractionVal\). This change strips out the foundational data structures and type classes used to represent and validate cron expressions, likely in preparation for a refactored architecture.

src/main · high confidence

Behavioural changes

Add Scala 2.12 compatibility shim for LazyList

A new compatibility file (compat.scala) was added to the Scala 2.12 source directory to alias the Scala 2.13 LazyList type to the Scala 2.12 Stream type. This change enables the core library to compile on Scala 2.12 by providing the necessary type aliases, supporting the broader addition of Scala 2.13 as a compilation target.

modules/core/shared/src/main/scala-2.12 · high confidence

Atto parser now supports uppercase day-of-week names

The Atto-based cron parser in the \modules/atto\ module now accepts uppercase day-of-week abbreviations (e.g., 'MON', 'TUE') in addition to the existing lowercase ones. This change ensures that day-of-week fields are case-insensitive, allowing users to specify days using either case without triggering parse errors.

modules/atto · high confidence

Atto parser promoted as default with configurable parser support

The default parser for cron expressions has been changed to Atto, replacing the previous implementation. Users can now explicitly select a different parser by using the new \withParser\ method on the \Cron\ entry point, which accepts a \Parser\ instance and returns a \CronImpl\ configured with that specific parser.

modules/core/js/src/main/scala/cron4s, modules/core/jvm · high confidence

Cron expression parsing now supports custom parsers

The native module's Cron entry point now exposes a \withParser\ method, allowing users to explicitly select an alternative parsing implementation instead of relying on the default. This change accompanies the promotion of \atto\ as the default parser and the deprecation of the previous \parserc\ parser, giving users control over the parsing engine used for cron expressions.

modules/core/native · high confidence

JavaScript Date handling now uses UTC for all operations and string representations

On the JavaScript platform, cron4s now treats \scala.scalajs.js.Date\ instances as strictly UTC. All date arithmetic (adding seconds, minutes, hours, days, months, or weeks) and field access (getting or setting seconds, minutes, hours, day of month, month, or day of week) uses UTC methods (e.g., \getUTCHours\, \setUTCSeconds\) instead of local time methods. Additionally, the default string representation of a Date is now its UTC string (via \toUTCString()\), and equality checks compare all UTC components including milliseconds. This ensures consistent behavior regardless of the user's local timezone.

modules/core/js/src/main/scala/cron4s/lib · high confidence

Parser-combinator parser implementation moved to new module and marked deprecated

The parser-combinator based cron parser has been reorganized into a dedicated \modules/parserc\ module, introducing new internal components (\base.scala\, \lexer.scala\, \parser.scala\) to handle tokenization and parsing logic. For users, the public entry point \cron4s.parsing.Parser\ is now explicitly marked as deprecated since version 0.8.0 in favor of the atto parser, signaling that this implementation is no longer the recommended approach for parsing cron expressions.

modules/parserc · high confidence

Refactor cron expression internals to use a new ADT-based parser and instance traits

The cron expression module has been restructured to introduce a new Abstract Syntax Tree (ADT) for parsing, replacing the previous internal representation. This change adds new files defining core expression nodes (such as EachNode, AnyNode, ConstNode, and BetweenNode) and establishes dedicated instance traits (CronExprInstances, DateCronExprInstances, TimeCronExprInstances) to provide Cats Eq and Show instances for the various cron expression types. Additionally, a new FieldExpr trait is introduced to handle field-specific matching and implication logic, enabling a more modular and type-safe approach to evaluating cron schedules.

modules/core/shared/src/main/scala/cron4s/expr · high confidence

Test coverage

Added JMH benchmarks for cron expression parsing and validation; Added JavaScript-specific cron date-time tests; Added Joda-Time integration tests; Added cross-platform tests for cron parser comparison; Added native test suite for parser combinators; Added property-based and regression tests for cron expression validation; Added property-based tests for Predicate algebraic laws; Added property-based tests for cron expression AST nodes; Added property-based tests for the cron expression parser; Added test suite for Java 8 java.time integration; Added test suites for DateTime cron and node operations; Added validation and unit tests for cron expression parsing.

Dependencies

Major build system overhaul and Scala 3 support

The build configuration has been significantly restructured, upgrading the project to support Scala versions 2.13.18, 2.12.17, and 3.3.6. This change includes migrating the organization to \com.github.alonsodomin.cron4s\, integrating MiMa for binary compatibility checking, and adding comprehensive settings for Scala.js, code coverage, and publishing. The previous dependency on \scala-parser-combinators\ is removed from the base configuration in favor of a more modular setup.

(dependencies) · high confidence

Migrate build infrastructure to SBT 1.12 and modernize dependency management

The project's build system has been significantly upgraded, moving from SBT 0.13.9 to version 1.12.13. This migration includes a comprehensive restructuring of dependency management: \project/Dependencies.scala\ and \project/CompilerPlugins.scala\ have been introduced to centralize library versions (such as Cats 2.13.0, Circe 0.14.16, and Doobie 0.13.4) and compiler plugins (Kind Projector 0.13.4, Better Monadic For 0.3.1), replacing ad-hoc configurations. The build now supports cross-compilation for JVM, JavaScript, and Native platforms using sbt-scalajs 1.21.0 and sbt-scala-native 0.5.12, with CI workflows configured via sbt-github-actions 0.31.0 to validate all three targets.

project · high confidence

Housekeeping

Repository initialization and build configuration

The repository has been initialized with essential project metadata and configuration files. This includes the addition of an Apache 2.0 license, a code of conduct, and a comprehensive README with build and usage instructions. The build environment is configured with specific JVM options for memory and compilation, a \.scalafmt.conf\ for code formatting (version 3.11.1, Scala 2.13 dialect), and a \.mergify.yml\ for automated pull request merging. Additionally, the \.gitignore\ has been updated to exclude IDE-specific files (VSCode, Metals, Bloop) and lock files, while a \CHANGELOG.md\ documents historical changes including parser upgrades and version bumps.

(repo-wide) · high confidence

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

How this codebase got here

Baseline

  • First survey — no prior run to compare against. CAI 55.

Lenses

  • Code Health 98
  • Architecture 100
  • Maturity 38
  • Readiness 58
  • Security 70

Changes since last survey

  • 300 commits — 289 feature/other, 11 fixes

By area

  • project/plugins.sbt — 89 commits
  • (root) — 77 commits
  • project/Dependencies.scala — 49 commits
  • project/build.properties — 32 commits
  • modules/core — 15 commits
  • .github/workflows — 9 commits
  • (repo) — 5 commits
  • docs/src — 4 commits
  • modules/testkit — 3 commits
  • bench/src — 2 commits
  • modules/atto — 2 commits
  • modules/parserc — 2 commits
  • project/CompilerPlugins.scala — 2 commits
  • scripts/travis-build.sh — 2 commits
  • tests/shared — 2 commits
  • .github/FUNDING.yml — 1 commit
  • modules/doobie — 1 commit
  • modules/kernel — 1 commit
  • scripts/travis-release.sh — 1 commit
  • tests/js — 1 commit

Notable commits

  • fix: Fix MiMa findings (#337)
  • fix: Fix compilation error in bench module (#336)
  • fix: Fix doc generation failure due to @JSExportTopLevel not being on the classpath (#552)
  • fix: Fix exception thrown when expression is too short (#335)
  • fix: fix: ParserAdaptater can be package-private
  • fix: fix: make atto parser faster than the scala parser combinator one
  • fix: fix: mark parserc parser as deprecated
  • fix: fix: remove overly strict EveryNode validator check for step frequency (#714)
  • fix: fix: scalafmt PR broke master, apply scalafmt by hand
  • fix: fix: support uppercase daysOfWeek and make atto compatible with literal daysOfWeek ranges
  • fix: fix: the CI fails because of a specific js Date behavior (#589)
  • change: Add 'Reformat with scalafmt 3.8.4' to .git-blame-ignore-revs
  • change: Add 'Reformat with scalafmt 3.8.5' to .git-blame-ignore-revs
  • change: Add 'Reformat with scalafmt 3.9.7' to .git-blame-ignore-revs
  • change: Add BlackDuck scanning to the source code (#180)
  • change: Add Java 11 to the compile matrix (#190)
  • change: Add Scala 2.13 compilation target (#142)
  • change: Add a package.json file
  • change: Add a validate command alias
  • change: Add better-monadic-for compiler plugin
  • …and 280 more

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

Survey your own repository

alonsodomin/cron4s was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.

About this page

  • The score is its most recent published measurement, taken on 20 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
  • Measured at commit 096347390412e386ecacea1c695a4a3c46f5c256 — the exact code this score is about.
  • Scored under rubric-2026.09.15 — the same rubric and the same method as every other entry in this index.
  • Measured by watchdog.canine.dev using codehealth-analyzer preprod-b51f968c9b10.