Handle multi-day holidays.
Some countries (e.g. Russia, or Vietnam) have holidays which span several days. Rather than using `holiday.date` from the date-holidays library, we can check the `.start` (inclusive) and `.end` (exclusive) dates, and use these to show multiple holiday days on the calendar. However since these properties return a `Date` representing the start of the day in that country, rather than an ISO string like `.date` does, we also need to pass in the current browser `timezone` to the library, so that we show the correct dates to the user.
This commit is contained in:
@@ -33,14 +33,18 @@ export function getHolidaysForYear(countryCode: string, year: number, stateCode?
|
|||||||
// The date-holidays lib has translations for many holidays, but defaults to using the language of the country.
|
// The date-holidays lib has translations for many holidays, but defaults to using the language of the country.
|
||||||
// We can pass in the browser's preferred languages (though the lib doesn't fall back, e.g. from `de-AT` to `de`)
|
// We can pass in the browser's preferred languages (though the lib doesn't fall back, e.g. from `de-AT` to `de`)
|
||||||
const languages = navigator.languages.map(lang => lang.split('-')[0]);
|
const languages = navigator.languages.map(lang => lang.split('-')[0]);
|
||||||
const opts = { languages }
|
// Start/end dates are returned in that country/state's time zone, so we need to provide our time zone to localise
|
||||||
|
const opts = { languages, timezone: Intl.DateTimeFormat().resolvedOptions().timeZone };
|
||||||
const hd = stateCode ? new Holidays(countryCode, stateCode, opts) : new Holidays(countryCode, opts);
|
const hd = stateCode ? new Holidays(countryCode, stateCode, opts) : new Holidays(countryCode, opts);
|
||||||
return hd.getHolidays(year)
|
return hd.getHolidays(year)
|
||||||
.filter(holiday => holiday.type === 'public')
|
.filter(holiday => holiday.type === 'public')
|
||||||
.map(holiday => ({
|
.flatMap(holiday =>
|
||||||
date: new Date(holiday.date),
|
// To handle single- and multi-day holidays, we generate a holiday entry for each day in the period
|
||||||
name: holiday.name
|
Array.from({ length: daysBetween(holiday.start, holiday.end) }, (_, i) => ({
|
||||||
}));
|
date: new Date(holiday.start.getFullYear(), holiday.start.getMonth(), holiday.start.getDate() + i),
|
||||||
|
name: holiday.name,
|
||||||
|
}))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Optimize days off to create the longest possible chains
|
// Optimize days off to create the longest possible chains
|
||||||
|
|||||||
Reference in New Issue
Block a user