Holidays
Holiday rules and observed days
A holiday can be a rule: a date every year, the nth or last weekday of a month, or a day relative to Easter. The observed option moves holidays that fall on a weekend to a working day.
ts
import { createWorkCalendar } from 'temporal-workdays';
const usFederal = createWorkCalendar({
observed: 'nearest', // Saturday moves to Friday, Sunday to Monday
holidays: [
'01-01',
{ name: 'MLK Day', month: 1, dayOfWeek: 1, week: 3 },
{ name: 'Memorial Day', month: 5, dayOfWeek: 1, week: -1 },
{ name: 'Juneteenth', month: 6, day: 19, from: 2021 },
'07-04',
{ name: 'Thanksgiving', month: 11, dayOfWeek: 4, week: 4 },
'12-25',
],
});
// July 4, 2026 is a Saturday, so it is observed on Friday the 3rd.
usFederal.isHoliday(Temporal.PlainDate.from('2026-07-03')); // → true
usFederal.isHoliday(Temporal.PlainDate.from('2026-11-26')); // → true
// New Year's Day 2022 was a Saturday, so it was observed on Friday, December 31, 2021.
usFederal.isHoliday(Temporal.PlainDate.from('2021-12-31')); // → true
const england = createWorkCalendar({
observed: 'next', // the next free working day
holidays: [{ name: 'Good Friday', easter: -2 }, { name: 'Easter Monday', easter: 1 }, '12-25', '12-26'],
});
england.isHoliday(Temporal.PlainDate.from('2026-04-03')); // → true
// Christmas 2021 was a Saturday and Boxing Day a Sunday. They were observed on the 27th and 28th.
england.isHoliday(Temporal.PlainDate.from('2021-12-28')); // → true| Rule | Example |
|---|---|
| A date every year | '12-25' or { month: 12, day: 25 } |
The nth weekday of a month (-1 last) | { month: 11, dayOfWeek: 4, week: 4 } |
| A day relative to Easter Sunday | { easter: -2 } or { easter: 1, orthodox: true } |
| One date | '2026-07-03' or { date: '2026-07-03' } |
| Options for any rule | offset (days), from and to (years), observed, name |
observed can be 'nearest', 'next', 'previous' or 'none' (the default), for the whole calendar or for one rule. The US federal and England and Wales rules above match the data in date-holidays for every year from 1990 to 2060, and Easter matches it for 1900 to 2100. The tests in test/holiday-rules.test.ts check this.
Holidays from date-holidays
date-holidays has holiday data for over 200 countries. fromDateHolidays turns it into options:
ts
import Holidays from 'date-holidays';
import { createWorkCalendar, fromDateHolidays } from 'temporal-workdays';
const bavaria = createWorkCalendar({
...fromDateHolidays(new Holidays('DE', 'BY'), { types: ['public', 'bank'] }),
hours: [['09:00', '17:00']],
});
bavaria.isWorkday(Temporal.PlainDate.from('2026-12-25')); // → false
bavaria.getWorkingHours(Temporal.PlainDate.from('2026-12-24')); // → [['09:00', '14:00']]typeschooses which holiday types close the business. The default is['public'].- A day that a holiday covers completely is a holiday. A day it covers in part keeps shorter hours, like Christmas Eve from 14:00.
- The answers don't depend on the time zone of the machine.
date-holidays' ownisHoliday(new Date(…))does: run in India, it says US Thanksgiving is not a holiday. temporal-workdaysdoesn't depend ondate-holidays. Install it yourself to use this.
To add your own holidays, wrap the function it returns:
ts
import Holidays from 'date-holidays';
import { fromDateHolidays, isWorkday } from 'temporal-workdays';
const us = fromDateHolidays(new Holidays('US'));
const companyDays = ['2026-12-24'];
const options = { ...us, holidays: (date) => us.holidays(date) || companyDays.includes(date.toString()) };
isWorkday(Temporal.PlainDate.from('2026-12-24'), options); // → false
isWorkday(Temporal.PlainDate.from('2026-11-26'), options); // → false