or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

date-operations.mdexpression-parsing.mdfield-system.mdfile-parsing.mdindex.mdschedule-iteration.md
tile.json

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