CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-cron-parser

Node.js library for parsing crontab instructions with timezone support, DST handling, and iterator capabilities

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

expression-parsing.mddocs/

Expression Parsing

Core functionality for parsing cron expressions with extensive syntax support, validation, and configuration options. Supports both standard 5-field and extended 6-field formats with predefined expressions.

Capabilities

Parse Method

Main method for parsing cron expressions into CronExpression objects.

/**
 * Parses a cron expression and returns a CronExpression object
 * @param expression - The cron expression to parse (5 or 6 fields)
 * @param options - Optional parsing configuration
 * @returns Configured CronExpression instance
 * @throws Error if expression is invalid or validation fails
 */
static parse(expression: string, options?: CronExpressionOptions): CronExpression;

interface CronExpressionOptions {
  /** Current date for iteration starting point. Defaults to current UTC time */
  currentDate?: Date | string | number | CronDate;
  /** End date of iteration range. Sets iteration range end point */
  endDate?: Date | string | number | CronDate;
  /** Start date of iteration range. Sets iteration range start point */
  startDate?: Date | string | number | CronDate;
  /** Timezone (e.g., 'Europe/London', 'America/New_York') */
  tz?: string;
  /** Original expression string (for toString() method) */
  expression?: string;
  /** Seed for H character randomization */
  hashSeed?: string;
  /** Enable strict mode validation */
  strict?: boolean;
}

Usage Examples:

import { CronExpressionParser } from "cron-parser";

// Basic parsing
const daily = CronExpressionParser.parse('0 0 * * *');
const everyTwoMinutes = CronExpressionParser.parse('*/2 * * * *');

// With options
const londnTime = CronExpressionParser.parse('0 9 * * 1-5', {
  tz: 'Europe/London',
  currentDate: '2023-01-01T00:00:00Z'
});

// Predefined expressions
const hourly = CronExpressionParser.parse('@hourly');
const weekdays = CronExpressionParser.parse('@weekdays');

// Strict mode (requires 6 fields, no ambiguous day specifications)
try {
  const strict = CronExpressionParser.parse('0 0 12 * * 1', { strict: true });
} catch (err) {
  console.log('Strict mode validation failed');
}

Predefined Expressions

Commonly used cron expressions with human-readable aliases.

enum PredefinedExpressions {
  '@yearly' = '0 0 0 1 1 *',      // Once a year at midnight of January 1
  '@annually' = '0 0 0 1 1 *',    // Alias for @yearly
  '@monthly' = '0 0 0 1 * *',     // Once a month at midnight of first day
  '@weekly' = '0 0 0 * * 0',      // Once a week at midnight on Sunday
  '@daily' = '0 0 0 * * *',       // Once a day at midnight
  '@hourly' = '0 0 * * * *',      // Once an hour at the beginning
  '@minutely' = '0 * * * * *',    // Once a minute
  '@secondly' = '* * * * * *',    // Once a second
  '@weekdays' = '0 0 0 * * 1-5',  // Every weekday at midnight
  '@weekends' = '0 0 0 * * 0,6'   // Every weekend at midnight
}

Usage Examples:

// All of these are equivalent to '0 0 0 * * *'
const daily1 = CronExpressionParser.parse('@daily');
const daily2 = CronExpressionParser.parse('0 0 0 * * *');

// Weekdays only (Monday through Friday)
const workDays = CronExpressionParser.parse('@weekdays');
console.log('Next workday:', workDays.next().toString());

Cron Expression Format

Understanding the cron expression format and field positions.

// Cron format: [second] minute hour dayOfMonth month dayOfWeek
// Field positions and ranges:

interface CronFormat {
  /** Optional - seconds field (0-59). If omitted, defaults to 0 */
  second?: SixtyRange;
  /** Required - minutes field (0-59) */
  minute: SixtyRange;
  /** Required - hours field (0-23) */
  hour: HourRange;
  /** Required - day of month field (1-31, L) */
  dayOfMonth: DayOfMonthRange;
  /** Required - month field (1-12, JAN-DEC) */
  month: MonthRange;
  /** Required - day of week field (0-7, SUN-SAT, L, #) */
  dayOfWeek: DayOfWeekRange;
}

// Field value types
type SixtyRange = 0 | 1 | 2 | ... | 59;
type HourRange = 0 | 1 | 2 | ... | 23;
type DayOfMonthRange = 1 | 2 | 3 | ... | 31 | 'L';
type MonthRange = 1 | 2 | 3 | ... | 12;
type DayOfWeekRange = 0 | 1 | 2 | ... | 7 | 'L';

Special Characters:

  • * - Any value (wildcard)
  • ? - Any value (alias for *)
  • , - Value list separator (e.g., 1,3,5)
  • - - Range of values (e.g., 1-5)
  • / - Step values (e.g., */5 every 5th, 10/15 every 15th starting from 10)
  • L - Last day of month/week
  • # - Nth day of month (e.g., 1#2 = second Monday)
  • H - Randomized value (requires hashSeed option)

Month and Day Aliases:

enum Months {
  jan = 1, feb = 2, mar = 3, apr = 4, may = 5, jun = 6,
  jul = 7, aug = 8, sep = 9, oct = 10, nov = 11, dec = 12
}

enum DayOfWeek {
  sun = 0, mon = 1, tue = 2, wed = 3, thu = 4, fri = 5, sat = 6
}

enum CronUnit {
  Second = 'Second',
  Minute = 'Minute', 
  Hour = 'Hour',
  DayOfMonth = 'DayOfMonth',
  Month = 'Month',
  DayOfWeek = 'DayOfWeek'
}

Usage Examples:

// Using month names
const monthly = CronExpressionParser.parse('0 0 1 JAN *');  // Same as '0 0 1 1 *'

// Using day names  
const weekends = CronExpressionParser.parse('0 0 * * SAT,SUN');  // Same as '0 0 * * 6,0'

// Complex expressions
const complex = CronExpressionParser.parse('0 30 9-17/2 * * MON-FRI');
// Runs at 30 minutes past every 2nd hour from 9-17 on weekdays

// Last day patterns
const lastDay = CronExpressionParser.parse('0 0 L * *');  // Last day of every month
const lastFriday = CronExpressionParser.parse('0 0 * * 5L'); // Last Friday of every month

// Nth day patterns  
const firstMonday = CronExpressionParser.parse('0 0 * * 1#1'); // First Monday of every month
const thirdWednesday = CronExpressionParser.parse('0 0 * * 3#3'); // Third Wednesday of every month

Strict Mode Validation

Enhanced validation mode that enforces stricter parsing rules.

interface StrictModeRules {
  /** Prevents simultaneous setting of both dayOfMonth and dayOfWeek fields */
  noDayOfMonthAndDayOfWeekTogether: boolean;
  /** Requires all 6 fields to be present (second, minute, hour, dayOfMonth, month, dayOfWeek) */
  requireSixFields: boolean;
  /** Rejects empty expressions that would default to '0 * * * * *' */
  noEmptyExpressions: boolean;
}

Usage Examples:

// This will throw in strict mode - uses both dayOfMonth (12) and dayOfWeek (1)
try {
  CronExpressionParser.parse('0 0 12 * * 1', { strict: true });
} catch (err) {
  console.log('Error:', err.message);
  // Error: Cannot use both dayOfMonth and dayOfWeek together in strict mode!
}

// This will throw in strict mode - only 5 fields provided
try {
  CronExpressionParser.parse('0 20 15 * *', { strict: true });
} catch (err) {
  console.log('Error:', err.message);
  // Error: Invalid cron expression, expected 6 fields
}

// Valid strict mode expressions
const validStrict1 = CronExpressionParser.parse('0 0 0 12 * *', { strict: true }); // dayOfWeek wildcard
const validStrict2 = CronExpressionParser.parse('0 0 0 * * 1', { strict: true });  // dayOfMonth wildcard

Error Handling

Common parsing errors and their meanings.

// Common error types thrown during parsing
interface ParsingErrors {
  InvalidExpressionError: "Invalid cron expression";
  TooManyFieldsError: "Invalid cron expression, too many fields";
  InvalidCharactersError: "Invalid characters, got value: [value]";
  ConstraintError: "Constraint error, got value [value] expected range [min]-[max]";
  InvalidRangeError: "Invalid range: [min]-[max], min > max";
  StrictModeError: "Cannot use both dayOfMonth and dayOfWeek together in strict mode!";
  ValidationError: "Validation error, cannot resolve alias [alias]";
}

Usage Examples:

// Handle parsing errors gracefully
function safeParse(expression: string, options?: CronExpressionOptions) {
  try {
    return CronExpressionParser.parse(expression, options);
  } catch (error) {
    if (error.message.includes('Invalid characters')) {
      console.log('Expression contains invalid characters');
    } else if (error.message.includes('Constraint error')) {
      console.log('Field value out of allowed range');
    } else if (error.message.includes('strict mode')) {
      console.log('Strict mode validation failed');
    } else {
      console.log('General parsing error:', error.message);
    }
    return null;
  }
}

const result = safeParse('0 0 32 * *'); // Day 32 doesn't exist
// Output: Field value out of allowed range

Install with Tessl CLI

npx tessl i tessl/npm-cron-parser

docs

date-operations.md

expression-parsing.md

field-system.md

file-parsing.md

index.md

schedule-iteration.md

tile.json