recurring-dates
v1.0.4
Published
Vanilla JS and React hook for generating recurring dates
Readme
recurring-dates
This is an updated and renamed version of the the-recurring-dates package.
Tiny toolkit for recurring schedules. Exported APIs:
generateRecurringDates(config): returns{ text, dates }getRecurringDates(config): shorthand aliasuseRecurringDates(config): React hook that keeps the list in sync
Supports daily, weekly, monthly, and yearly rules with ordinals, weekday filters, custom intervals, and explicit exclusions.
Install
npm install recurring-datesESM is the default export. UMD bundles live at dist/index.umd.js for CDN or legacy builds.
Quick Start
import { generateRecurringDates } from "recurring-dates";
const { text, dates } = generateRecurringDates({
STARTS_ON: "01-01-2025",
ENDS_ON: "31-01-2025",
FREQUENCY: "W",
WEEK_DAYS: ["MON", "THU"],
EXCLUDE_DATES: ["13-01-2025"],
});
console.log(text); // Every week on MON, THU
console.log(dates); // ["02-01-2025", ...]import { useRecurringDates } from "recurring-dates";
export function Demo() {
const dates = useRecurringDates({
STARTS_ON: "2025-06-01",
ENDS_ON: "2025-08-31",
FREQUENCY: "M",
MONTH_DATES: [1, 15],
FORMAT: "YYYY-MM-DD",
});
return <pre>{JSON.stringify(dates, null, 2)}</pre>;
}CDN:
<script src="https://cdn.jsdelivr.net/recurring-dates/dist/index.umd.js"></script>
<script>
const { getRecurringDates } = RecurringDates;
console.log(
getRecurringDates({ STARTS_ON: "01-01-2025", ENDS_ON: "05-01-2025" }),
);
</script>Config Reference
| Key | Type | Notes |
| --------------- | --------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| STARTS_ON | string | Required. Parsed with FORMAT. |
| ENDS_ON | string | Required. Must be >= STARTS_ON. |
| FREQUENCY | "D" "W" "M" "Y" | Defaults to daily. |
| INTERVAL | number | Defaults to 1. Skips cycles when > 1. |
| MONTH_DATES | number[] | Days of month for monthly/yearly patterns. |
| WEEK_DAYS | string[] | ISO weekday codes (MON to SUN). |
| WEEK_ORDINALS | string[] | FIRST, SECOND, THIRD, FOURTH, FIFTH, LAST (yearly only). |
| MONTH_NAMES | string[] | JAN to DEC (yearly only). |
| EXCLUDE_DATES | string[] | Dates to drop after generation. |
| FORMAT | string | Input/output date format. Default DD-MM-YYYY. |
| TIMEZONE | string | Optional. IANA timezone identifier (e.g., America/New_York, Europe/London, Asia/Tokyo). Defaults to user's local timezone. |
Validation errors return { dates: [], error }. Successful calls omit the error field.
Timezone Support
Use the TIMEZONE option to generate dates in specific timezones. Supports all IANA timezone identifiers.
import { generateRecurringDates, getTimezoneList } from "recurring-dates";
// Generate recurring dates in a specific timezone
const { dates, text } = generateRecurringDates({
STARTS_ON: "01-01-2025",
ENDS_ON: "31-01-2025",
FREQUENCY: "D",
TIMEZONE: "America/New_York",
});
console.log(text); // Every day
console.log(dates); // ["01-01-2025", "02-01-2025", ...]
// Get list of supported timezones with offsets
const timezones = getTimezoneList();
// [
// { timezone: "America/New_York", offset: "-05:00", offset_hours: -5 },
// { timezone: "Europe/London", offset: "+00:00", offset_hours: 0 },
// { timezone: "Asia/Tokyo", offset: "+09:00", offset_hours: 9 },
// ...
// ]
// Common timezones
const COMMON_ZONES = [
"America/New_York", // Eastern Time
"America/Chicago", // Central Time
"America/Denver", // Mountain Time
"America/Los_Angeles", // Pacific Time
"Europe/London", // UK
"Europe/Paris", // Central Europe
"Asia/Tokyo", // Japan
"Asia/Shanghai", // China
"Australia/Sydney", // Australia
"UTC", // Coordinated Universal Time
];Timezone utilities are exported for advanced usage:
import {
isValidTimezone,
getUserTimezone,
getTimezoneOffset,
getTimezoneOffsetString,
formatDateInTimezone,
getTimezoneList,
SUPPORTED_TIMEZONES,
} from "recurring-dates";
// Check if a timezone is valid
isValidTimezone("America/New_York"); // true
isValidTimezone("Invalid/Zone"); // false
// Get user's current timezone
const userTz = getUserTimezone(); // "America/New_York"
// Get timezone offset in hours
getTimezoneOffset("Asia/Tokyo"); // 9
getTimezoneOffset("America/New_York"); // -5 (EST) or -4 (EDT)
// Get offset string
getTimezoneOffsetString("Asia/Tokyo"); // "+09:00"
getTimezoneOffsetString("America/New_York"); // "-05:00"
// Format date in specific timezone
const date = new Date(2025, 2, 5);
formatDateInTimezone(date, "America/New_York"); // "03/05/2025"
// Get all supported timezones
const allTimezones = SUPPORTED_TIMEZONES; // Array of IANA timezone stringsTesting
This package includes comprehensive test coverage with 154 passing test cases across 8 test suites:
daily.test.js- Daily recurrence patternsweekly.test.js- Weekly recurrence with weekday filtersmonthly.test.js- Monthly recurrence patternsyearly.test.js- Yearly recurrence with ordinalscurrent-format.test.js- Date format handlingedge-cases.test.js- Edge case scenariosvalidation.test.js- Input validationtimezone.test.js- Timezone support and multi-timezone scheduling (24 timezone tests)
Run tests locally:
npm test # Run all tests
npm run test:watch # Watch mode
npm run test:coverage # Generate coverage reportReal-World Use Cases
See TIMEZONE_USECASES.md for 10+ practical examples:
- 🌍 Global team meeting scheduler
- 🏥 Medical appointment reminders across regions
- 🎤 International conference scheduling
- 🔧 SaaS maintenance windows per timezone
- 🔥 E-commerce flash sales by region
- 📅 Project deadline tracking
- 📹 Video release scheduling
- 💪 Gym class schedules across locations
- 💳 Subscription billing by timezone
- 📦 Shipment scheduling for global delivery
Links
- Demo: https://recurring-dates.thehardik.in
- Docs and issues: https://github.com/hardik-143/recurring-dates
- npm: https://www.npmjs.com/package/recurring-dates
