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

date-operations.mddocs/

Date Operations

Timezone-aware date operations with automatic DST (Daylight Saving Time) handling and cron-specific functionality. Built on Luxon for robust date manipulation.

Capabilities

CronDate Constructor

Create timezone-aware date instances with multiple input format support.

/**
 * Constructs a new CronDate instance with timezone support
 * @param timestamp - The timestamp to initialize with (optional, defaults to current time)
 * @param tz - The timezone to use (optional, defaults to system timezone)
 * @throws Error if timestamp format is unrecognized
 */
constructor(timestamp?: CronDate | Date | number | string, tz?: string);

Usage Examples:

import { CronDate } from "cron-parser";

// Create from current time
const now = new CronDate();
console.log('Current time:', now.toString());

// Create from Date object
const fromDate = new CronDate(new Date('2023-01-01T12:00:00Z'));

// Create from timestamp
const fromTimestamp = new CronDate(1672574400000); // Same as above

// Create from ISO string
const fromISO = new CronDate('2023-01-01T12:00:00Z');

// Create from other formats
const fromRFC2822 = new CronDate('Sun, 01 Jan 2023 12:00:00 GMT');
const fromSQL = new CronDate('2023-01-01 12:00:00');

// With timezone
const london = new CronDate('2023-01-01T12:00:00Z', 'Europe/London');
const tokyo = new CronDate('2023-01-01T12:00:00Z', 'Asia/Tokyo');
const nyc = new CronDate('2023-01-01T12:00:00Z', 'America/New_York');

console.log('London:', london.toString());
console.log('Tokyo:', tokyo.toString());
console.log('NYC:', nyc.toString());

// Copy constructor
const copied = new CronDate(london); // Preserves timezone and DST info

Standard Date Methods

Standard JavaScript Date API methods with timezone awareness.

// Time retrieval methods (local timezone)
getTime(): number;           // Unix timestamp in milliseconds
getFullYear(): number;       // Full year (e.g., 2023)
getMonth(): number;          // Month (0-11, January = 0)
getDate(): number;           // Day of month (1-31)
getDay(): number;            // Day of week (0-6, Sunday = 0)
getHours(): number;          // Hours (0-23)
getMinutes(): number;        // Minutes (0-59)
getSeconds(): number;        // Seconds (0-59)
getMilliseconds(): number;   // Milliseconds (0-999)

// UTC time retrieval methods
getUTCDate(): number;        // UTC day of month (1-31)
getUTCFullYear(): number;    // UTC full year
getUTCDay(): number;         // UTC day of week (0-6, Sunday = 0)
getUTCMonth(): number;       // UTC month (0-11, January = 0)
getUTCHours(): number;       // UTC hours (0-23)
getUTCMinutes(): number;     // UTC minutes (0-59)
getUTCSeconds(): number;     // UTC seconds (0-59)

// Time setting methods  
setDate(d: number): void;        // Set day of month
setFullYear(y: number): void;    // Set year
setDay(d: number): void;         // Set day of week
setMonth(m: number): void;       // Set month (0-11)
setHours(h: number): void;       // Set hours
setMinutes(m: number): void;     // Set minutes
setSeconds(s: number): void;     // Set seconds
setMilliseconds(ms: number): void; // Set milliseconds

// String representation and conversion
toString(): string;          // Human-readable date string
toDate(): Date;             // Convert to JavaScript Date object
toISOString(): string | null; // ISO string representation
toJSON(): string | null;     // JSON string representation

Usage Examples:

const cronDate = new CronDate('2023-06-15T14:30:45.123Z', 'America/New_York');

// Get date components (all timezone-aware)
console.log('Year:', cronDate.getFullYear());        // 2023
console.log('Month:', cronDate.getMonth());          // 5 (June, 0-indexed)
console.log('Date:', cronDate.getDate());            // 15
console.log('Day:', cronDate.getDay());              // 4 (Thursday)
console.log('Hours:', cronDate.getHours());          // 10 (14:30 UTC = 10:30 EDT)
console.log('Minutes:', cronDate.getMinutes());      // 30
console.log('Seconds:', cronDate.getSeconds());      // 45
console.log('Milliseconds:', cronDate.getMilliseconds()); // 123

// Unix timestamp
console.log('Timestamp:', cronDate.getTime());       // 1686837045123

// Access UTC values
console.log('UTC Year:', cronDate.getUTCFullYear());     // 2023
console.log('UTC Month:', cronDate.getUTCMonth());       // 5 (June, 0-indexed)  
console.log('UTC Date:', cronDate.getUTCDate());         // 15
console.log('UTC Hours:', cronDate.getUTCHours());       // 14 (original UTC time)

// Modify date components
cronDate.setHours(15);
console.log('New hours:', cronDate.getHours());          // 15

cronDate.setMonth(11); // December (0-indexed)
console.log('New month:', cronDate.getMonth());          // 11

cronDate.setMilliseconds(0);
console.log('Zeroed ms:', cronDate.getSeconds(), cronDate.getMilliseconds()); // 45, 0

// String representations and conversions
console.log('String:', cronDate.toString());
console.log('ISO String:', cronDate.toISOString());
console.log('JSON:', cronDate.toJSON());
console.log('JS Date:', cronDate.toDate());

Date Arithmetic

Add and subtract time units with automatic boundary handling.

// Addition methods - each advances to start of next unit
addYear(): void;    // Add 1 year
addMonth(): void;   // Add 1 month, reset to start of month
addDay(): void;     // Add 1 day, reset to start of day  
addHour(): void;    // Add 1 hour, reset to start of hour
addMinute(): void;  // Add 1 minute, reset to start of minute
addSecond(): void;  // Add 1 second

// Subtraction methods - each goes to end of previous unit (except second)
subtractYear(): void;   // Subtract 1 year
subtractMonth(): void;  // Subtract 1 month, go to end of previous month
subtractDay(): void;    // Subtract 1 day, go to end of previous day
subtractHour(): void;   // Subtract 1 hour, go to end of previous hour  
subtractMinute(): void; // Subtract 1 minute, go to end of previous minute
subtractSecond(): void; // Subtract 1 second

Usage Examples:

const date = new CronDate('2023-03-15T14:30:45Z');

// Addition - advances to start of next unit
date.addHour();
console.log('After addHour():', date.toString()); // 2023-03-15T15:00:00Z

date.addDay();  
console.log('After addDay():', date.toString()); // 2023-03-16T00:00:00Z

date.addMonth();
console.log('After addMonth():', date.toString()); // 2023-04-01T00:00:00Z

// Subtraction - goes to end of previous unit  
const date2 = new CronDate('2023-03-15T14:30:45Z');

date2.subtractHour();
console.log('After subtractHour():', date2.toString()); // 2023-03-15T13:59:59Z

date2.subtractDay();
console.log('After subtractDay():', date2.toString()); // 2023-03-14T23:59:59Z

// Seconds behave differently (exact arithmetic)
const date3 = new CronDate('2023-03-15T14:30:45Z');
date3.addSecond();
console.log('After addSecond():', date3.toString()); // 2023-03-15T14:30:46Z

date3.subtractSecond();  
console.log('After subtractSecond():', date3.toString()); // 2023-03-15T14:30:45Z

Generic Date Operations

Generic methods for programmatic date manipulation.

/**
 * Add a unit of time to the current CronDate
 * @param unit - The time unit to add
 */
addUnit(unit: TimeUnit): void;

/**
 * Subtract a unit of time from the current CronDate  
 * @param unit - The time unit to subtract
 */
subtractUnit(unit: TimeUnit): void;

/**
 * Perform a generic date operation
 * @param verb - Add or Subtract operation
 * @param unit - The time unit to operate on
 */
invokeDateOperation(verb: DateMathOp, unit: TimeUnit): void;

/**
 * Apply date operation with skip count (internal method)
 * @param verb - Add or Subtract operation  
 * @param unit - The time unit to operate on
 * @param skip - Number of units to skip
 */
applyDateOperation(verb: DateMathOp, unit: TimeUnit, skip: number): void;

enum TimeUnit {
  Second = 'Second',
  Minute = 'Minute',
  Hour = 'Hour', 
  Day = 'Day',
  Month = 'Month',
  Year = 'Year'
}

enum DateMathOp {
  Add = 'Add',
  Subtract = 'Subtract'
}

Usage Examples:

import { CronDate, TimeUnit, DateMathOp } from "cron-parser";

const date = new CronDate('2023-03-15T14:30:45Z');

// Generic unit operations
date.addUnit(TimeUnit.Hour);
console.log('Added hour:', date.toString());

date.subtractUnit(TimeUnit.Day);  
console.log('Subtracted day:', date.toString());

// Generic operation with verb and unit
date.invokeDateOperation(DateMathOp.Add, TimeUnit.Month);
console.log('Added month:', date.toString());

date.invokeDateOperation(DateMathOp.Subtract, TimeUnit.Year);
console.log('Subtracted year:', date.toString());

// Programmatic date manipulation
const operations = [
  { verb: DateMathOp.Add, unit: TimeUnit.Day },
  { verb: DateMathOp.Add, unit: TimeUnit.Hour },
  { verb: DateMathOp.Subtract, unit: TimeUnit.Minute }
];

operations.forEach(op => {
  date.invokeDateOperation(op.verb, op.unit);
  console.log(`After ${op.verb} ${op.unit}:`, date.toString());
});

Cron-Specific Date Checks

Special date checks useful for cron expression evaluation.

/**
 * Determine if the current date is the last day of the month
 * @returns True if this is the last day of the month
 */
isLastDayOfMonth(): boolean;

/**
 * Determine if the current date is the last occurrence of this weekday in the month
 * @returns True if this is the last occurrence of this weekday
 */
isLastWeekdayOfMonth(): boolean;

Usage Examples:

// Test last day of month
const feb28_2023 = new CronDate('2023-02-28T12:00:00Z'); // Non-leap year
const feb28_2024 = new CronDate('2024-02-28T12:00:00Z'); // Leap year  
const feb29_2024 = new CronDate('2024-02-29T12:00:00Z'); // Leap year last day
const mar31_2023 = new CronDate('2023-03-31T12:00:00Z'); // 31-day month

console.log('Feb 28, 2023 is last day:', feb28_2023.isLastDayOfMonth()); // true
console.log('Feb 28, 2024 is last day:', feb28_2024.isLastDayOfMonth()); // false  
console.log('Feb 29, 2024 is last day:', feb29_2024.isLastDayOfMonth()); // true
console.log('Mar 31, 2023 is last day:', mar31_2023.isLastDayOfMonth()); // true

// Test last weekday of month
const lastMonday = new CronDate('2023-01-30T12:00:00Z');    // Last Monday of Jan 2023
const notLastMonday = new CronDate('2023-01-23T12:00:00Z'); // Not last Monday
const lastFriday = new CronDate('2023-01-27T12:00:00Z');    // Last Friday of Jan 2023

console.log('Jan 30, 2023 is last Monday:', lastMonday.isLastWeekdayOfMonth());    // true
console.log('Jan 23, 2023 is last Monday:', notLastMonday.isLastWeekdayOfMonth()); // false
console.log('Jan 27, 2023 is last Friday:', lastFriday.isLastWeekdayOfMonth());    // true

// Practical usage with cron expressions using 'L'
import { CronExpressionParser } from "cron-parser";

const lastDayOfMonth = CronExpressionParser.parse('0 0 L * *');
const testDate = new CronDate('2023-03-31T00:00:00Z');

if (testDate.isLastDayOfMonth()) {
  console.log('Date matches last day pattern:', lastDayOfMonth.includesDate(testDate));
}

DST (Daylight Saving Time) Support

Automatic handling of DST transitions with hour tracking.

/**
 * Get/set daylight savings start time
 */
get dstStart(): number | null;
set dstStart(value: number | null);

/**
 * Get/set daylight savings end time  
 */
get dstEnd(): number | null;
set dstEnd(value: number | null);

Usage Examples:

// DST handling is automatic when using timezones
const eastern = new CronDate('2023-03-12T07:00:00Z', 'America/New_York'); // Spring forward day

console.log('EST hour:', eastern.getHours()); // Automatically handles DST

// DST properties are managed internally
console.log('DST start hour:', eastern.dstStart); // null or hour number
console.log('DST end hour:', eastern.dstEnd);     // null or hour number  

// DST affects cron scheduling automatically
const dstExpression = CronExpressionParser.parse('0 2 * * *', {
  tz: 'America/New_York',
  currentDate: '2023-03-11T00:00:00Z' // Day before spring forward
});

// This will automatically handle the missing 2 AM hour on spring forward
try {
  const next = dstExpression.next();
  console.log('Next 2 AM (handles DST):', next.toString());
} catch (error) {
  console.log('DST transition handled:', error.message);
}

// Fall back example  
const fallBack = CronExpressionParser.parse('0 1 * * *', {
  tz: 'America/New_York',
  currentDate: '2023-11-04T00:00:00Z' // Day before fall back
});

const nextFallBack = fallBack.next();
console.log('Next 1 AM (during fall back):', nextFallBack.toString());

Constants and Utilities

Useful constants and utilities for date operations.

/**
 * Array of days in each month (accounting for leap year maximum)
 */
const DAYS_IN_MONTH: readonly number[] = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];

/**
 * Static method to check if a year is a leap year
 * @param year - The year to check
 * @returns True if the year is a leap year
 */
static isLeapYear(year: number): boolean;

Usage Examples:

import { CronDate, DAYS_IN_MONTH } from "cron-parser";

// Use days in month constant
console.log('Days in February (max):', DAYS_IN_MONTH[1]); // 29
console.log('Days in December:', DAYS_IN_MONTH[11]);      // 31

// Check leap years (internal static method, not typically needed)
// Note: This is a private static method, shown for understanding
const isLeap2024 = (2024 % 4 === 0 && 2024 % 100 !== 0) || 2024 % 400 === 0;
console.log('2024 is leap year:', isLeap2024); // true

const isLeap2023 = (2023 % 4 === 0 && 2023 % 100 !== 0) || 2023 % 400 === 0;
console.log('2023 is leap year:', isLeap2023); // false

// Practical usage: validate day of month for specific month/year
function isValidDayOfMonth(day: number, month: number, year: number): boolean {
  const daysInMonth = DAYS_IN_MONTH[month - 1]; // Convert to 0-indexed
  
  // Handle February in non-leap years
  if (month === 2 && day === 29) {
    return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
  }
  
  return day >= 1 && day <= daysInMonth;
}

console.log('Feb 29, 2024 valid:', isValidDayOfMonth(29, 2, 2024)); // true
console.log('Feb 29, 2023 valid:', isValidDayOfMonth(29, 2, 2023)); // false
console.log('Apr 31, 2023 valid:', isValidDayOfMonth(31, 4, 2023)); // false

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