or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-cronstrue

Convert cron expressions into human readable descriptions

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/cronstrue@3.2.x

To install, run

npx @tessl/cli install tessl/npm-cronstrue@3.2.0

index.mddocs/

Cronstrue

Cronstrue is a JavaScript library that parses cron expressions and outputs human-readable descriptions of cron schedules. It supports all cron expression special characters, 5-7 part expressions, Quartz Job Scheduler compatibility, and internationalization with 39 languages.

Package Information

  • Package Name: cronstrue
  • Package Type: npm
  • Language: JavaScript/TypeScript
  • Installation: npm install cronstrue

Core Imports

import cronstrue from "cronstrue";

For CommonJS:

const cronstrue = require("cronstrue");

For full internationalization support:

import cronstrue from "cronstrue/i18n";
const cronstrue = require("cronstrue/i18n");

For individual locale loading:

import cronstrue from "cronstrue";
import "cronstrue/locales/fr";
import "cronstrue/locales/es";

Basic Usage

import cronstrue from "cronstrue";

// Basic cron expression conversion
console.log(cronstrue.toString("* * * * *"));
// Output: "Every minute"

console.log(cronstrue.toString("0 23 ? * MON-FRI"));
// Output: "At 11:00 PM, Monday through Friday"

// With options
console.log(cronstrue.toString("0 23 * * *", { verbose: true }));
// Output: "At 11:00 PM, every day"

console.log(cronstrue.toString("23 14 * * SUN#2", { use24HourTimeFormat: true }));
// Output: "At 14:23, on the second Sunday of the month"

// With localization
console.log(cronstrue.toString("*/5 * * * *", { locale: "fr" })); // requires i18n import
// Output: "Toutes les 5 minutes"

Architecture

Cronstrue is built around several key components:

  • ExpressionDescriptor: Main class that orchestrates the parsing and description generation process
  • CronParser: Handles parsing and validation of cron expressions into component parts
  • Internationalization System: Provides locale-specific translations and formatting rules
  • RangeValidator: Validates cron expression components are within valid ranges
  • StringUtilities: Utility functions for string manipulation and formatting

The library follows a parse-then-describe pattern where expressions are first validated and parsed into components, then each component is processed through locale-specific description generators.

Capabilities

Cron Expression Conversion

Converts cron expressions to human-readable descriptions with extensive customization options.

/**
 * Converts a cron expression into a description a human can read
 * @param expression - The cron expression
 * @param options - Optional configuration object
 * @returns Human readable description
 */
function toString(
  expression: string,
  options?: Options
): string;

interface Options {
  /** If exception occurs when trying to parse expression, whether to throw or return error message (Default: true) */
  throwExceptionOnParseError?: boolean;
  /** Whether to use a verbose description (Default: false) */
  verbose?: boolean;
  /** Whether to interpret cron expression DOW 1 as Sunday or Monday (Default: true) */
  dayOfWeekStartIndexZero?: boolean;
  /** Whether to interpret January as 0 or 1 (Default: false) */
  monthStartIndexZero?: boolean;
  /** If true, descriptions will use 24-hour clock (Default: false, varies by locale) */
  use24HourTimeFormat?: boolean;
  /** The locale to use (Default: "en") */
  locale?: string | null;
  /** @deprecated Timezone offset in minutes - no longer supported */
  tzOffset?: number;
}

Expression Descriptor Class

Main class for advanced usage and custom initialization.

class ExpressionDescriptor {
  /** Available locale objects */
  static locales: { [name: string]: Locale };
  /** Default locale identifier */
  static defaultLocale: string;
  /** Special cron characters: ["/", "-", ",", "*"] */
  static specialCharacters: string[];

  /** The cron expression being processed */
  expression: string;
  /** Parsed components of the cron expression */
  expressionParts: string[];
  /** Configuration options */
  options: Options;
  /** Locale object for translations */
  i18n: Locale;

  /**
   * Creates new ExpressionDescriptor instance
   * @param expression - Cron expression
   * @param options - Configuration options
   */
  constructor(expression: string, options: Options);

  /**
   * Converts a cron expression into a description a human can read
   * @param expression - The cron expression
   * @param options - Optional configuration object
   * @returns Human readable description
   */
  static toString(expression: string, options?: Options): string;

  /**
   * Initializes the ExpressionDescriptor with locale data
   * @param localesLoader - Loader for locale data
   * @param defaultLocale - Default locale (defaults to "en")
   */
  static initialize(localesLoader: LocaleLoader, defaultLocale?: string): void;

  /**
   * Gets the full human-readable description (protected method)
   * @protected
   */
  protected getFullDescription(): string;
}

Cron Expression Parser

Core parsing engine that handles expression validation and component extraction.

/**
 * Parses and validates cron expressions into component parts
 */
class CronParser {
  /** The cron expression being parsed */
  expression: string;
  /** Whether DOW 1 represents Sunday (true) or Monday (false) */
  dayOfWeekStartIndexZero: boolean;
  /** Whether January is represented as 0 (true) or 1 (false) */
  monthStartIndexZero: boolean;

  /**
   * Creates a new CronParser instance
   * @param expression - Cron expression to parse
   * @param dayOfWeekStartIndexZero - DOW interpretation (default: true)
   * @param monthStartIndexZero - Month interpretation (default: false)
   */
  constructor(expression: string, dayOfWeekStartIndexZero?: boolean, monthStartIndexZero?: boolean);

  /**
   * Parses the cron expression into component parts
   * @returns Array of parsed expression parts [seconds, minutes, hours, dayOfMonth, month, dayOfWeek, year]
   */
  parse(): string[];

  /**
   * Handles special cron expressions like @yearly, @monthly, etc.
   * @param expression - Special expression to parse
   * @returns Standard cron expression equivalent
   */
  parseSpecial(expression: string): string;
}

Range Validation

Validation utilities for ensuring cron expression components are within valid ranges.

/**
 * Validates cron expression component ranges
 */
class RangeValidator {
  /** Validates seconds range (0-59) */
  static secondRange(parse: string): void;
  /** Validates minutes range (0-59) */
  static minuteRange(parse: string): void;
  /** Validates hours range (0-23) */
  static hourRange(parse: string): void;
  /** Validates day of month range (1-31) */
  static dayOfMonthRange(parse: string): void;
  /** Validates month range (1-12 or 0-11 based on monthStartIndexZero) */
  static monthRange(parse: string, monthStartIndexZero: boolean): void;
  /** Validates day of week range (0-7 or 1-7 based on dayOfWeekStartIndexZero) */
  static dayOfWeekRange(parse: string, dayOfWeekStartIndexZero: boolean): void;
}

Internationalization System

Complete localization support with 39 available languages.

interface LocaleLoader {
  /** Loads locale data into provided object */
  load(availableLocales: { [name: string]: Locale }): void;
}

interface Locale {
  /** Default time format for locale */
  use24HourTimeFormatByDefault(): boolean;
  /** Error message when expression parsing fails */
  anErrorOccuredWhenGeneratingTheExpressionD(): string;
  /** Basic time translations */
  everyMinute(): string;
  everyHour(): string;
  everySecond(): string;
  atSpace(): string;
  at(): string;
  spaceAnd(): string;
  /** AM/PM indicators (optional) */
  pm?(): string;
  am?(): string;
  /** @reboot translation (optional) */
  atReboot?(): string;
  /** Controls whether AM/PM appears before or after time (optional) */
  setPeriodBeforeTime?(): boolean;
  /** Custom verbosity replacements for concise mode (optional) */
  conciseVerbosityReplacements?(): Record<string, string>;
  /** Days of week with grammatical case support (optional) */
  daysOfTheWeekInCase?(caseForm?: number): string[];
  /** Months with grammatical case support (optional) */
  monthsOfTheYearInCase?(caseForm?: number): string[];
  /** Template strings for intervals */
  everyX0Seconds(s?: string): string;
  everyX0Minutes(s?: string): string;
  everyX0Hours(s?: string): string;
  everyX0Days(s?: string): string;
  everyX0Months(s?: string): string;
  everyX0Years(s?: string): string;
  /** Date and time component arrays */
  daysOfTheWeek(): string[];
  monthsOfTheYear(): string[];
  /** Advanced grammar support */
  daysOfTheWeekInCase?(f?: number): string[];
  monthsOfTheYearInCase?(f?: number): string[];
  /** Text replacements for concise mode */
  conciseVerbosityReplacements?(): Record<string, string>;
  /** Additional translation methods for complex expressions */
  everyMinuteBetweenX0AndX1(): string;
  secondsX0ThroughX1PastTheMinute(): string;
  atX0SecondsPastTheMinute(s?: string): string;
  atX0SecondsPastTheMinuteGt20(): string | null;
  minutesX0ThroughX1PastTheHour(): string;
  atX0MinutesPastTheHour(s?: string): string;
  atX0MinutesPastTheHourGt20(): string | null;
  betweenX0AndX1(): string;
  atX0(): string;
  commaEveryDay(): string;
  commaEveryX0DaysOfTheWeek(s?: string): string;
  commaX0ThroughX1(s?: string): string;
  commaAndX0ThroughX1(s?: string): string;
  commaMonthX0ThroughMonthX1(): string | null;
  commaYearX0ThroughYearX1(): string | null;
  first(s?: string): string;
  second(s?: string): string;
  third(s?: string): string;
  fourth(s?: string): string;
  fifth(s?: string): string;
  commaOnThe(s?: string, day?: string): string;
  spaceX0OfTheMonth(): string;
  lastDay(): string;
  commaOnTheLastX0OfTheMonth(s?: string): string;
  commaOnlyOnX0(s?: string): string;
  commaAndOnX0(): string;
  commaEveryX0Months(s?: string): string;
  commaOnlyInX0(): string;
  commaOnlyInMonthX0?(): string;
  commaOnlyInYearX0?(): string;
  commaOnTheLastDayOfTheMonth(): string;
  commaOnTheLastWeekdayOfTheMonth(): string;
  commaDaysBeforeTheLastDayOfTheMonth(s?: string): string;
  firstWeekday(): string;
  weekdayNearestDayX0(): string;
  commaOnTheX0OfTheMonth(): string;
  commaEveryX0Days(s?: string): string;
  commaBetweenDayX0AndX1OfTheMonth(s?: string): string;
  commaOnDayX0OfTheMonth(s?: string): string;
  commaEveryX0Years(s?: string): string;
  commaStartingX0(): string;
  dayX0?(): string;
  setPeriodBeforeTime?(): boolean;
}

Locale Loaders

Pre-built locale loaders for different use cases.

/** Loads English locale only - lightweight option */
class enLocaleLoader implements LocaleLoader {
  load(availableLocales: { [name: string]: Locale }): void;
}

/** Loads all 39 available locales - full internationalization */
class allLocalesLoader implements LocaleLoader {
  load(availableLocales: { [name: string]: Locale }): void;
}

Individual Locale Classes

Direct access to individual locale implementations for advanced usage.

// Individual locale classes exported from cronstrue/i18n/allLocales
export {
  en, af, ar, be, bg, ca, cs, da, de, es, fa, fi, fr, he, hr, hu,
  id, it, ja, ko, my, nb, nl, pl, pt_BR, pt_PT, ro, ru, sk, sl,
  sv, sw, th, tr, uk, vi, zh_CN, zh_TW
} from "cronstrue/i18n/allLocales";

// Usage example
import { fr, de, es } from "cronstrue/i18n/allLocales";
import cronstrue from "cronstrue";

// Initialize with specific locales
cronstrue.ExpressionDescriptor.initialize({
  load: (locales) => {
    locales['fr'] = new fr();
    locales['de'] = new de();
    locales['es'] = new es();
  }
});

Utility Functions

String manipulation utilities used internally but available for advanced usage.

class StringUtilities {
  /**
   * Replaces %s placeholders in template with provided values
   * @param template - Template string with %s placeholders
   * @param values - Replacement values
   * @returns Formatted string
   */
  static format(template: string, ...values: string[]): string;

  /**
   * Checks if text contains any of the search strings
   * @param text - Text to search in
   * @param searchStrings - Array of strings to search for
   * @returns True if any search string is found
   */
  static containsAny(text: string, searchStrings: string[]): boolean;
}

Supported Features

Cron Expression Formats

  • 5-part: minute hour day-of-month month day-of-week
  • 6-part: second minute hour day-of-month month day-of-week OR minute hour day-of-month month day-of-week year
  • 7-part: second minute hour day-of-month month day-of-week year

Special Characters

  • * - Wildcard (any value)
  • / - Step values (e.g., */5 = every 5)
  • , - Lists (e.g., 1,3,5)
  • - - Ranges (e.g., 1-5)
  • ? - No specific value (day-of-month/day-of-week)
  • L - Last (e.g., last day of month)
  • W - Weekday nearest (e.g., 15W)
  • # - Nth occurrence (e.g., SUN#2 = 2nd Sunday)

Special Expressions

  • @yearly / @annually - Once a year (0 0 1 1 *)
  • @monthly - Once a month (0 0 1 * *)
  • @weekly - Once a week (0 0 * * 0)
  • @daily / @midnight - Once a day (0 0 * * *)
  • @hourly - Every hour (0 * * * *)
  • @reboot - At startup (special case)

Available Locales

39 supported languages: en (English), af (Afrikaans), ar (Arabic), be (Belarusian), bg (Bulgarian), ca (Catalan), cs (Czech), da (Danish), de (German), es (Spanish), fa (Farsi), fi (Finnish), fr (French), he (Hebrew), hr (Croatian), hu (Hungarian), id (Indonesian), it (Italian), ja (Japanese), ko (Korean), my (Malay), nb (Norwegian), nl (Dutch), pl (Polish), pt_BR (Portuguese Brazil), pt_PT (Portuguese Portugal), ro (Romanian), ru (Russian), sk (Slovakian), sl (Slovenian), sv (Swedish), sw (Swahili), th (Thai), tr (Turkish), uk (Ukrainian), vi (Vietnamese), zh_CN (Chinese Simplified), zh_TW (Chinese Traditional)

Command Line Usage

When installed globally, cronstrue provides a CLI interface supporting multiple argument formats:

# Install globally
npm install -g cronstrue

# Single quoted expression
cronstrue "*/5 * * * *"
# Output: Every 5 minutes

cronstrue "@daily"
# Output: At 12:00 AM, every day

# 5 arguments: minute hour day-of-month month day-of-week
cronstrue 1 2 3 4 5
# Output: At 02:01 AM, on day 3 of the month, and on Friday, only in April

# 6 arguments: second minute hour day-of-month month day-of-week
cronstrue 0 1 2 3 4 5
# Output: At 02:01:00 AM, on day 3 of the month, and on Friday, only in April

# 7 arguments: second minute hour day-of-month month day-of-week year
cronstrue 0 1 2 3 4 5 2025
# Output: At 02:01:00 AM, on day 3 of the month, and on Friday, only in April, only in 2025

# Error handling for incorrect argument count
cronstrue 1 2 3
# Output: Error: too few arguments (3): 1 2 3
# Usage (5 args): cronstrue minute hour day-of-month month day-of-week
# or
# Usage (6 args): cronstrue second minute hour day-of-month month day-of-week
# or
# Usage (7 args): cronstrue second minute hour day-of-month month day-of-week year

Browser Usage

UMD Module

<script src="https://unpkg.com/cronstrue@latest/dist/cronstrue.min.js"></script>
<script>
  var cronstrue = window.cronstrue;
  console.log(cronstrue.toString("*/5 * * * *"));
</script>

With Internationalization

<script src="https://unpkg.com/cronstrue@latest/dist/cronstrue-i18n.min.js"></script>
<script>
  var cronstrue = window.cronstrue;
  console.log(cronstrue.toString("*/5 * * * *", { locale: "fr" }));
</script>

Individual Locales

<script src="https://unpkg.com/cronstrue@latest/dist/cronstrue.min.js"></script>
<script src="https://unpkg.com/cronstrue@latest/locales/fr.min.js"></script>
<script src="https://unpkg.com/cronstrue@latest/locales/es.min.js"></script>
<script>
  var cronstrue = window.cronstrue;
  console.log(cronstrue.toString("*/5 * * * *", { locale: "fr" }));
</script>

Advanced Import Patterns

For advanced usage, you can import components directly:

// Direct component imports
import { ExpressionDescriptor } from "cronstrue/dist/expressionDescriptor";
import { CronParser } from "cronstrue/dist/cronParser";
import { StringUtilities } from "cronstrue/dist/stringUtilities";
import { RangeValidator } from "cronstrue/dist/rangeValidator";

// Individual locale imports
import { en, fr, de } from "cronstrue/i18n/allLocales";

// Direct locale loader imports
import { enLocaleLoader } from "cronstrue/i18n/enLocaleLoader";
import { allLocalesLoader } from "cronstrue/i18n/allLocalesLoader";

// Advanced usage example
const parser = new CronParser("*/5 * * * *", true, false);
const parts = parser.parse();
console.log(parts); // ["*", "*/5", "*", "*", "*"]

// Custom validation
try {
  RangeValidator.minuteRange("*/75"); // Invalid - minutes only go 0-59
} catch (error) {
  console.error("Invalid minute range");
}

Error Handling

Parse Error Behavior

import cronstrue from "cronstrue";

// Default: throws exception on invalid expression
try {
  cronstrue.toString("invalid expression");
} catch (error) {
  console.error(error); // Throws parsing error
}

// Alternative: return error message
const result = cronstrue.toString("invalid expression", {
  throwExceptionOnParseError: false
});
console.log(result); // Returns locale-specific error message

Range Validation

// Automatic validation occurs during parsing
try {
  cronstrue.toString("75 * * * *"); // Invalid minute (>59)
} catch (error) {
  console.error("Minute values must be between 0 and 59");
}

try {
  cronstrue.toString("* 25 * * *"); // Invalid hour (>23)
} catch (error) {
  console.error("Hour values must be between 0 and 23");
}

Locale Fallback

// If specified locale doesn't exist, falls back to first available locale
const description = cronstrue.toString("* * * * *", { locale: "nonexistent" });
// Console warning: "Locale 'nonexistent' could not be found; falling back to 'en'."

// Deprecated tzOffset warning
const result = cronstrue.toString("* * * * *", { tzOffset: 300 });
// Console warning: "'tzOffset' option has been deprecated and is no longer supported."