A powerful JavaScript/TypeScript library for calculating eligible run dates based on complex scheduling rules. Perfect for job schedulers, task automation, and business calendar management.
npm install @laxmandarji/schedule-date-calculatorbash
npm install @laxmandarji/schedule-date-calculator
`
Usage
The library supports both CommonJS and ES Modules:
`javascript
// CommonJS
const { ScheduleConfig } = require('@laxmandarji/schedule-date-calculator');
// ES Modules
import { ScheduleConfig } from '@laxmandarji/schedule-date-calculator';
`
Configuration
Create a new schedule configuration:
`javascript
const config = new ScheduleConfig({
CALENDARS: {
WORKWEEK: {
WORKDAYS: [1, 2, 3, 4, 5], // Mon-Fri
HOLIDAYS: ["2024-12-25", "2024-01-01"]
}
},
WEEKDAYS_CALENDAR: "WORKWEEK",
WEEKDAYS: ["D1", "D2"], // First and second working days
MONTHS: ["JAN", "FEB", "MAR"] // First quarter
});
`
$3
- CALENDARS: Object containing named calendars with workdays and holidays
- WORKDAYS: Array of working days (0-6, where 0 is Sunday)
- HOLIDAYS: Array of holiday dates in "YYYY-MM-DD" format
- WEEKDAYS_CALENDAR: Name of the calendar to use for weekday calculations
- WEEKDAYS: Array of weekday specifications
- WEEK_MONTH_RELATION: Relationship between week and month rules ("AND" or "OR", defaults to "OR")
- MONTH_CALENDAR: Name of the calendar to use for monthday calculations
- MONTHDAYS: Array of monthday specifications
- MONTHS: Array of month names (e.g., ["JAN", "FEB", "MAR"])
Methods
$3
Completely replaces the current configuration with a new one. All properties are reset to their default values if not specified in the new configuration.
`javascript
config.change({
CALENDARS: {
NEWCAL: {
WORKDAYS: [1, 2, 3], // Mon-Wed
HOLIDAYS: ["2024-12-25"]
}
},
WEEKDAYS: ["D1"], // First working day only
MONTHS: ["JAN"] // January only
});
`
$3
Updates specific properties of the configuration while keeping others unchanged.
`javascript
config.update({
WEEKDAYS: ["D1", "D2"], // Only updates WEEKDAYS
MONTHS: ["JAN", "FEB"] // Only updates MONTHS
});
`
$3
Adds or updates a calendar in the configuration.
`javascript
config.addCalendar(
"CUSTOM_CAL",
[1, 2, 3, 4, 5], // Mon-Fri
["2024-12-25", "2024-01-01"]
);
`
$3
Checks if a specific date is eligible according to the configuration.
`javascript
const date = new Date('2024-01-02');
const isEligible = config.isDateEligible(date);
`
$3
Gets all eligible dates for a specific year.
`javascript
const dates = config.getEligibleDates(2024);
`
$3
Validates the current configuration.
`javascript
const validation = config.validate();
if (!validation.isValid) {
console.error('Configuration errors:', validation.errors);
}
`
Examples
$3
`javascript
const config = new ScheduleConfig({
CALENDARS: {
WORKWEEK: {
WORKDAYS: [1, 2, 3, 4, 5], // Mon-Fri
HOLIDAYS: ["2024-12-25"]
}
},
WEEKDAYS_CALENDAR: "WORKWEEK",
WEEKDAYS: ["D1"], // First working day
MONTHS: ["JAN", "FEB"] // Jan-Feb only
});
// Get eligible dates for 2024
const dates = config.getEligibleDates(2024);
console.log('Eligible dates:', dates);
`
$3
`javascript
// Initial configuration
const config = new ScheduleConfig({
CALENDARS: {
WORKWEEK: {
WORKDAYS: [1, 2, 3, 4, 5],
HOLIDAYS: ["2024-12-25"]
}
}
});
// Complete configuration change
config.change({
CALENDARS: {
CUSTOM: {
WORKDAYS: [1, 2, 3],
HOLIDAYS: ["2024-01-01"]
}
},
WEEKDAYS: ["D1"],
MONTHS: ["JAN"]
});
// Partial update
config.update({
WEEKDAYS: ["D1", "D2"]
});
`
Configuration Guide
$3
Define business calendars with working days and holidays:
`typescript
const config = new ScheduleConfig({
CALENDARS: {
US_BUSINESS: {
WORKDAYS: [1, 2, 3, 4, 5], // Monday-Friday
HOLIDAYS: ["2025-01-01", "2025-12-25"]
},
ASIA_BUSINESS: {
WORKDAYS: [1, 2, 3, 4, 5, 6], // Monday-Saturday
HOLIDAYS: ["2025-01-01"]
}
}
});
`
$3
Multiple formats for weekday scheduling:
`typescript
{
WEEKDAYS_CALENDAR: "US_BUSINESS",
WEEKDAYS: [
"1", // Every Monday
">3", // Run on next working day if Wednesday is not a working day
"<3", // Run on previous working day if Wednesday is not a working day
"+3", // Force run on Wednesday (even if holiday)
"-3", // Never run on Wednesday
"D2", // 2nd working day of each week
"D3W2" // Wednesday of 2nd week
]
}
`
$3
Flexible monthly scheduling:
`typescript
{
MONTH_CALENDAR: "US_BUSINESS",
MONTHDAYS: [
"WORKDAYS", // All working days
"-WORKDAYS", // No working days
"1", // 1st day of month
">15", // Run on next working day if 15th is not a working day
"<15", // Run on previous working day if 15th is not a working day
"+15", // Force run on 15th (even if holiday)
"-15", // Skip 15th
"D5", // 5th working day
"L1", // Last working day
"L5" // 5th to last working day
]
}
`
$3
Specify months to run:
`typescript
{
MONTHS: ["JAN", "APR", "JUL", "OCT"], // Quarterly
// or
MONTHS: ["ALL"] // Run every month
}
`
$3
Control how weekday and monthday rules combine:
`typescript
{
WEEK_MONTH_RELATION: "AND", // Must satisfy both conditions
// or
WEEK_MONTH_RELATION: "OR" // Must satisfy either condition (default)
}
`
Advanced Examples
$3
`typescript
const config = new ScheduleConfig({
CALENDARS: {
BUSINESS: {
WORKDAYS: [1, 2, 3, 4, 5],
HOLIDAYS: ["2025-01-01"]
}
},
MONTH_CALENDAR: "BUSINESS",
MONTHDAYS: ["WORKDAYS"], // Run on all working days
MONTHS: ["ALL"]
});
`
$3
`typescript
const config = new ScheduleConfig({
CALENDARS: {
BUSINESS: {
WORKDAYS: [1, 2, 3, 4, 5],
HOLIDAYS: ["2025-01-01"]
}
},
MONTH_CALENDAR: "BUSINESS",
MONTHDAYS: ["-WORKDAYS", "15"], // Run on non-working days and 15th
MONTHS: ["ALL"]
});
`
$3
`typescript
const config = new ScheduleConfig({
CALENDARS: {
BUSINESS: {
WORKDAYS: [1, 2, 3, 4, 5],
HOLIDAYS: ["2025-04-01"]
}
},
WEEKDAYS_CALENDAR: "BUSINESS",
WEEKDAYS: [
"D2W1", // Tuesday of first week
"D4W3", // Thursday of third week
">3" // Next working day after Wednesday
],
MONTHS: ["ALL"]
});
`
$3
`typescript
const config = new ScheduleConfig({
CALENDARS: {
BUSINESS: {
WORKDAYS: [1, 2, 3, 4, 5],
HOLIDAYS: ["2025-04-01"]
}
},
MONTH_CALENDAR: "BUSINESS",
MONTHDAYS: [
"WORKDAYS", // All working days
"-15", // Except the 15th
"L1" // And include the last working day
],
MONTHS: ["APR"]
});
`
API Reference
$3
The library is organized into logical namespaces:
#### utils
`typescript
import { utils } from '@laxmandarji/schedule-date-calculator';
utils.validateConfig(config);
utils.formatDate(date);
utils.getWeekOfMonth(date);
`
#### dateCalculators
`typescript
import { dateCalculators } from '@laxmandarji/schedule-date-calculator';
dateCalculators.isWorkingDay(date, calendar);
dateCalculators.getNthWorkdayOfMonth(date, n, calendar);
dateCalculators.getLastNthWorkdayOfMonth(date, n, calendar);
`
#### evaluators
`typescript
import { evaluators } from '@laxmandarji/schedule-date-calculator';
evaluators.evaluateWeekdays(date, config, calendars);
evaluators.evaluateMonthdays(date, config, calendars);
`
$3
#### Constructor
`typescript
const config = new ScheduleConfig(configObject);
`
#### Methods
##### isDateEligible(date)
`typescript
const date = new Date(2025, 3, 16);
const isEligible = config.isDateEligible(date);
`
##### getEligibleDates(year)
`typescript
const dates = config.getEligibleDates(2025);
`
##### validate()
`typescript
const validation = config.validate();
if (!validation.isValid) {
console.error(validation.errors);
}
``