@laxmandarji/schedule-date-calculator
v4.1.0
Published
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.
Maintainers
Readme
Schedule Date Calculator
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.
What's New in v4
Version 4.0.0
- Added "WORKDAYS" keyword support in MONTHDAYS rules to easily include or exclude all working days
- Improved exclusion rule handling - exclusions now take precedence and are evaluated first
- Enhanced performance by processing exclusions before inclusions
- Fixed edge cases in weekday and monthday rule evaluation
- Breaking change: Changed behavior of exclusion rules (-) to take precedence over inclusion rules
Features
- 📅 Define custom business calendars with working days and holidays
- 🔄 Flexible scheduling patterns (daily, weekly, monthly)
- 🎯 Advanced modifiers for precise scheduling control
- 📊 Support for complex business logic
- ⚡ Efficient date calculations with caching
- 🛡️ Comprehensive validation and error handling
- 📘 Full TypeScript support
- 🚀 Optimized performance
- 🧪 Modular architecture
Installation
npm install @laxmandarji/schedule-date-calculatorUsage
The library supports both CommonJS and ES Modules:
// CommonJS
const { ScheduleConfig } = require('@laxmandarji/schedule-date-calculator');
// ES Modules
import { ScheduleConfig } from '@laxmandarji/schedule-date-calculator';Configuration
Create a new schedule configuration:
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
});Configuration Options
CALENDARS: Object containing named calendars with workdays and holidaysWORKDAYS: 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 calculationsWEEKDAYS: Array of weekday specificationsWEEK_MONTH_RELATION: Relationship between week and month rules ("AND" or "OR", defaults to "OR")MONTH_CALENDAR: Name of the calendar to use for monthday calculationsMONTHDAYS: Array of monthday specificationsMONTHS: Array of month names (e.g., ["JAN", "FEB", "MAR"])
Methods
change(config)
Completely replaces the current configuration with a new one. All properties are reset to their default values if not specified in the new configuration.
config.change({
CALENDARS: {
NEWCAL: {
WORKDAYS: [1, 2, 3], // Mon-Wed
HOLIDAYS: ["2024-12-25"]
}
},
WEEKDAYS: ["D1"], // First working day only
MONTHS: ["JAN"] // January only
});update(newConfig)
Updates specific properties of the configuration while keeping others unchanged.
config.update({
WEEKDAYS: ["D1", "D2"], // Only updates WEEKDAYS
MONTHS: ["JAN", "FEB"] // Only updates MONTHS
});addCalendar(calendarName, workdays, holidays)
Adds or updates a calendar in the configuration.
config.addCalendar(
"CUSTOM_CAL",
[1, 2, 3, 4, 5], // Mon-Fri
["2024-12-25", "2024-01-01"]
);isDateEligible(date)
Checks if a specific date is eligible according to the configuration.
const date = new Date('2024-01-02');
const isEligible = config.isDateEligible(date);getEligibleDates(year)
Gets all eligible dates for a specific year.
const dates = config.getEligibleDates(2024);validate()
Validates the current configuration.
const validation = config.validate();
if (!validation.isValid) {
console.error('Configuration errors:', validation.errors);
}Examples
Basic Usage
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);Changing Configuration
// 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
Calendar Configuration
Define business calendars with working days and holidays:
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"]
}
}
});Weekday Rules
Multiple formats for weekday scheduling:
{
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
]
}Monthday Rules
Flexible monthly scheduling:
{
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
]
}Month Selection
Specify months to run:
{
MONTHS: ["JAN", "APR", "JUL", "OCT"], // Quarterly
// or
MONTHS: ["ALL"] // Run every month
}Week-Month Relation
Control how weekday and monthday rules combine:
{
WEEK_MONTH_RELATION: "AND", // Must satisfy both conditions
// or
WEEK_MONTH_RELATION: "OR" // Must satisfy either condition (default)
}Advanced Examples
Working Days Only Schedule
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"]
});Non-Working Days Only Schedule
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"]
});Complex Weekly Pattern
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"]
});Holiday-Aware Monthly Schedule
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
Namespaces
The library is organized into logical namespaces:
utils
import { utils } from '@laxmandarji/schedule-date-calculator';
utils.validateConfig(config);
utils.formatDate(date);
utils.getWeekOfMonth(date);dateCalculators
import { dateCalculators } from '@laxmandarji/schedule-date-calculator';
dateCalculators.isWorkingDay(date, calendar);
dateCalculators.getNthWorkdayOfMonth(date, n, calendar);
dateCalculators.getLastNthWorkdayOfMonth(date, n, calendar);evaluators
import { evaluators } from '@laxmandarji/schedule-date-calculator';
evaluators.evaluateWeekdays(date, config, calendars);
evaluators.evaluateMonthdays(date, config, calendars);ScheduleConfig Class
Constructor
const config = new ScheduleConfig(configObject);Methods
isDateEligible(date)
const date = new Date(2025, 3, 16);
const isEligible = config.isDateEligible(date);getEligibleDates(year)
const dates = config.getEligibleDates(2025);validate()
const validation = config.validate();
if (!validation.isValid) {
console.error(validation.errors);
}License
MIT License - see LICENSE file for details.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
Support
For support, please create an issue in the GitHub repository.
Author
Laxman Darji
