Cron time parsing, validation, and calculation utilities for working with cron expressions and scheduling. Provides both a comprehensive CronTime class and standalone utility functions for quick calculations.
Handles cron expression parsing, validation, and next execution time calculations with timezone and DST handling.
/**
* Class for parsing and calculating cron time schedules
* Supports cron expressions, Date objects, and Luxon DateTime objects
*/
class CronTime {
// Constructor overloads for timezone/utcOffset exclusivity
constructor(
source: string | Date | DateTime,
timeZone?: string | null,
utcOffset?: never
);
constructor(
source: string | Date | DateTime,
timeZone?: never,
utcOffset?: number | null
);
constructor(
source: string | Date | DateTime,
timeZone?: string | null,
utcOffset?: number | null
);
// Properties
readonly source: string | DateTime;
readonly timeZone?: string;
readonly utcOffset?: number;
readonly realDate: boolean;
// Static methods
static validateCronExpression(cronExpression: string): {
valid: boolean;
error?: CronError;
};
// Instance methods
sendAt(): DateTime;
sendAt(i: number): DateTime[];
getTimeout(): number;
toString(): string;
toJSON(): string[];
getNextDateFrom(start: Date | DateTime, timeZone?: string): DateTime;
}Constructor Parameters:
source - Cron expression string, JavaScript Date, or Luxon DateTime objecttimeZone - Timezone string (e.g., 'America/Los_Angeles'). Cannot be used with utcOffsetutcOffset - UTC offset in minutes. Cannot be used with timeZoneUsage Examples:
import { CronTime } from "cron";
// From cron expression
const cronTime = new CronTime('0 0 * * *'); // midnight daily
// With timezone
const cronTimeZone = new CronTime('0 0 * * *', 'America/New_York');
// With UTC offset (offset in minutes)
const cronOffset = new CronTime('0 0 * * *', null, -300); // UTC-5
// From Date object
const futureDate = new Date('2024-12-31T23:59:59Z');
const dateTime = new CronTime(futureDate);
// From Luxon DateTime
import { DateTime } from 'luxon';
const luxonTime = DateTime.now().plus({ hours: 1 });
const cronFromLuxon = new CronTime(luxonTime);Validate cron expressions without creating a CronTime instance.
/**
* Validate a cron expression
* @param cronExpression - Cron expression string to validate
* @returns Object with validation result and optional error
*/
static validateCronExpression(cronExpression: string): {
valid: boolean;
error?: CronError;
};Usage Examples:
// Valid expressions
let result = CronTime.validateCronExpression('0 0 * * *');
console.log(result.valid); // true
result = CronTime.validateCronExpression('*/5 * * * *');
console.log(result.valid); // true
// Invalid expression
result = CronTime.validateCronExpression('invalid');
console.log(result.valid); // false
console.error(result.error?.message); // Error details
// Check before creating CronTime
const expression = '0 0 29 2 *'; // Feb 29th
const validation = CronTime.validateCronExpression(expression);
if (validation.valid) {
const cronTime = new CronTime(expression);
console.log('Next execution:', cronTime.sendAt().toISO());
} else {
console.error('Invalid cron expression:', validation.error?.message);
}Methods for calculating execution times and intervals.
/**
* Calculate next execution time
* @returns Luxon DateTime object for next execution
*/
sendAt(): DateTime;
/**
* Calculate multiple future execution times
* @param i - Number of future executions to calculate
* @returns Array of Luxon DateTime objects
*/
sendAt(i: number): DateTime[];
/**
* Get milliseconds until next execution
* Can return negative value if calculation takes too long
* @returns Number of milliseconds until next execution
*/
getTimeout(): number;
/**
* Get next execution time from a specific start point
* @param start - Starting date/time for calculation
* @param timeZone - Optional timezone override
* @returns Luxon DateTime object for next execution
*/
getNextDateFrom(start: Date | DateTime, timeZone?: string): DateTime;Usage Examples:
const cronTime = new CronTime('0 */4 * * *'); // every 4 hours
// Next execution
const next = cronTime.sendAt();
console.log('Next execution:', next.toISO());
// Next 5 executions
const nextFive = cronTime.sendAt(5);
nextFive.forEach((date, i) => {
console.log(`Execution ${i + 1}:`, date.toISO());
});
// Milliseconds until next execution
const timeout = cronTime.getTimeout();
console.log('Execute in', timeout, 'milliseconds');
// Calculate from specific start time
const startTime = new Date('2024-01-01T00:00:00Z');
const nextFromStart = cronTime.getNextDateFrom(startTime);
console.log('Next from start:', nextFromStart.toISO());
// Handle negative timeout (missed execution)
if (timeout < 0) {
console.warn('Execution was missed by', Math.abs(timeout), 'ms');
}Methods for converting CronTime back to string representations.
/**
* Convert to cron string representation
* @returns Cron expression string
*/
toString(): string;
/**
* Get JSON representation of parsed cron components
* @returns Array of strings representing each cron field
*/
toJSON(): string[];Usage Examples:
const cronTime = new CronTime('*/15 9-17 * * 1-5');
// Get cron string
console.log(cronTime.toString()); // "*/15 9-17 * * 1-5"
// Get JSON representation
console.log(cronTime.toJSON());
// ["*/15", "9-17", "*", "*", "1-5"]
// Reconstruct from JSON
const jsonRep = cronTime.toJSON();
const reconstructed = jsonRep.join(' ');
console.log('Reconstructed:', reconstructed); // "*/15 9-17 * * 1-5"Quick utility functions for common time calculations without creating CronTime instances.
/**
* Get next execution time for a cron expression
* @param cronTime - Cron expression, Date, or DateTime
* @returns Luxon DateTime object for next execution
*/
function sendAt(cronTime: string | Date | DateTime): DateTime;
/**
* Get milliseconds until next execution
* @param cronTime - Cron expression, Date, or DateTime
* @returns Number of milliseconds until next execution
*/
function timeout(cronTime: string | Date | DateTime): number;
/**
* Validate a cron expression
* @param cronExpression - Cron expression string to validate
* @returns Object with validation result and optional error
*/
function validateCronExpression(cronExpression: string): {
valid: boolean;
error?: CronError;
};Usage Examples:
import { sendAt, timeout, validateCronExpression } from "cron";
// Quick next execution time
const nextDaily = sendAt('0 0 * * *');
console.log('Next daily execution:', nextDaily.toISO());
// Quick timeout calculation
const dailyTimeout = timeout('0 0 * * *');
console.log('Daily job executes in:', dailyTimeout, 'ms');
// Quick validation
const isValid = validateCronExpression('0 0 * * *');
console.log('Valid expression:', isValid.valid);
// With Date objects
const futureDate = new Date(Date.now() + 3600000); // 1 hour from now
const dateTimeout = timeout(futureDate);
console.log('Date execution in:', dateTimeout, 'ms');
// Validation in conditionals
if (validateCronExpression(userInput).valid) {
console.log('Starting job with expression:', userInput);
// Create and start job
} else {
console.error('Invalid cron expression provided');
}The cron expressions support enhanced 6-field format with second precision:
field allowed values
----- --------------
second 0-59
minute 0-59
hour 0-23
day of month 1-31
month 1-12 (or names: jan-dec)
day of week 0-7 (0 or 7 is Sunday, or names: sun-sat)// Standard patterns
'0 0 * * *' // Every day at midnight
'*/5 * * * *' // Every 5 minutes
'0 0 */2 * *' // Every 2 days at midnight
'0 9-17 * * 1-5' // Every hour from 9 AM to 5 PM, Monday to Friday
// With seconds
'*/30 * * * * *' // Every 30 seconds
'0 */15 * * * *' // Every 15 minutes (at :00 seconds)
// Using names
'0 0 * * mon-fri' // Weekdays at midnight
'0 0 1 jan *' // New Year's Day
// Preset expressions
'@yearly' // 0 0 0 1 1 *
'@monthly' // 0 0 0 1 * *
'@weekly' // 0 0 0 * * 0
'@daily' // 0 0 0 * * *
'@hourly' // 0 0 * * * *
'@minutely' // 0 * * * * *
'@secondly' // * * * * * *// System timezone (default)
const localTime = new CronTime('0 0 * * *');
// Specific timezone
const nyTime = new CronTime('0 0 * * *', 'America/New_York');
const utcTime = new CronTime('0 0 * * *', 'UTC');
// UTC offset (in minutes)
const offsetTime = new CronTime('0 0 * * *', null, -300); // UTC-5
// DST handling is automatic
const dstTime = new CronTime('0 2 * * *', 'America/New_York');
// Automatically handles spring forward and fall back