~/recurring-dates
docs

Yearly Frequency

The most powerful frequency mode. Generate dates using week ordinals, weekday codes, and month names — e.g. "Second Monday of January".

Required Fields

Yearly frequency requires all three: WEEK_ORDINALS, WEEK_DAYS, and MONTH_NAMES.

Basic: Second Monday of January

Second Monday of January
const result = generateRecurringDates({
  STARTS_ON: "01-01-2025",
  ENDS_ON: "31-12-2030",
  FREQUENCY: "Y",
  WEEK_ORDINALS: ["SECOND"],
  WEEK_DAYS: ["MON"],
  MONTH_NAMES: ["JAN"],
});

// text: "Every year on Second Monday of January"
// dates: ["13-01-2025", "12-01-2026", "11-01-2027", ...]

Multiple Months

First Friday of every quarter:

Quarterly First Fridays
const result = generateRecurringDates({
  STARTS_ON: "01-01-2025",
  ENDS_ON: "31-12-2025",
  FREQUENCY: "Y",
  WEEK_ORDINALS: ["FIRST"],
  WEEK_DAYS: ["FRI"],
  MONTH_NAMES: ["JAN", "APR", "JUL", "OCT"],
});

// text: "Every year on First Friday of January, April, July and October"

Last Weekday of Month

Use LAST ordinal to target the last occurrence:

Last Friday of December
const result = generateRecurringDates({
  STARTS_ON: "01-01-2025",
  ENDS_ON: "31-12-2025",
  FREQUENCY: "Y",
  WEEK_ORDINALS: ["LAST"],
  WEEK_DAYS: ["FRI"],
  MONTH_NAMES: ["DEC"],
});

// text: "Every year on Last Friday of December"

Multiple Ordinals & Days

Combine multiple ordinals, days, and months:

Complex Combination
const result = generateRecurringDates({
  STARTS_ON: "01-01-2025",
  ENDS_ON: "31-12-2025",
  FREQUENCY: "Y",
  WEEK_ORDINALS: ["FIRST", "THIRD"],
  WEEK_DAYS: ["MON", "WED"],
  MONTH_NAMES: ["MAR", "SEP"],
});

// text: "Every year on First and Third Monday and Wednesday of March and September"
// Generates: 1st Mon of Mar, 1st Wed of Mar, 3rd Mon of Mar, 3rd Wed of Mar,
//            1st Mon of Sep, 1st Wed of Sep, 3rd Mon of Sep, 3rd Wed of Sep

Every N Years

Use INTERVAL for multi-year cycles:

Biennial
const result = generateRecurringDates({
  STARTS_ON: "01-01-2025",
  ENDS_ON: "31-12-2035",
  FREQUENCY: "Y",
  WEEK_ORDINALS: ["FIRST"],
  WEEK_DAYS: ["MON"],
  MONTH_NAMES: ["JAN"],
  INTERVAL: 2,
});

// text: "Every 2 years on First Monday of January"

Ordinal Values

FIRST1st week
SECOND2nd week
THIRD3rd week
FOURTH4th week
FIFTH5th week
LASTLast week

Config Keys Used

STARTS_ON, ENDS_ON, FREQUENCY: "Y", WEEK_ORDINALS, WEEK_DAYS, MONTH_NAMES, INTERVAL, EXCLUDE_DATES, FORMAT.