UNPKG

react-calendar

Version:

Ultimate calendar for your React app.

85 lines (74 loc) 3.25 kB
import getUserLocale from 'get-user-locale'; const formatterCache = new Map(); function getFormatter( options: Intl.DateTimeFormatOptions, ): (locale: string | undefined, date: Date) => string { return function formatter(locale: string | undefined, date: Date): string { const localeWithDefault = locale || getUserLocale(); if (!formatterCache.has(localeWithDefault)) { formatterCache.set(localeWithDefault, new Map()); } const formatterCacheLocale = formatterCache.get(localeWithDefault); if (!formatterCacheLocale.has(options)) { formatterCacheLocale.set( options, new Intl.DateTimeFormat(localeWithDefault || undefined, options).format, ); } return formatterCacheLocale.get(options)(date); }; } /** * Changes the hour in a Date to ensure right date formatting even if DST is messed up. * Workaround for bug in WebKit and Firefox with historical dates. * For more details, see: * https://bugs.chromium.org/p/chromium/issues/detail?id=750465 * https://bugzilla.mozilla.org/show_bug.cgi?id=1385643 * * @param {Date} date Date. * @returns {Date} Date with hour set to 12. */ function toSafeHour(date: Date): Date { const safeDate = new Date(date); return new Date(safeDate.setHours(12)); } function getSafeFormatter( options: Intl.DateTimeFormatOptions, ): (locale: string | undefined, date: Date) => string { return (locale, date) => getFormatter(options)(locale, toSafeHour(date)); } const formatDateOptions = { day: 'numeric', month: 'numeric', year: 'numeric', } satisfies Intl.DateTimeFormatOptions; const formatDayOptions = { day: 'numeric' } satisfies Intl.DateTimeFormatOptions; const formatLongDateOptions = { day: 'numeric', month: 'long', year: 'numeric', } satisfies Intl.DateTimeFormatOptions; const formatMonthOptions = { month: 'long' } satisfies Intl.DateTimeFormatOptions; const formatMonthYearOptions = { month: 'long', year: 'numeric', } satisfies Intl.DateTimeFormatOptions; const formatShortWeekdayOptions = { weekday: 'short' } satisfies Intl.DateTimeFormatOptions; const formatWeekdayOptions = { weekday: 'long' } satisfies Intl.DateTimeFormatOptions; const formatYearOptions = { year: 'numeric' } satisfies Intl.DateTimeFormatOptions; export const formatDate: (locale: string | undefined, date: Date) => string = getSafeFormatter(formatDateOptions); export const formatDay: (locale: string | undefined, date: Date) => string = getSafeFormatter(formatDayOptions); export const formatLongDate: (locale: string | undefined, date: Date) => string = getSafeFormatter(formatLongDateOptions); export const formatMonth: (locale: string | undefined, date: Date) => string = getSafeFormatter(formatMonthOptions); export const formatMonthYear: (locale: string | undefined, date: Date) => string = getSafeFormatter(formatMonthYearOptions); export const formatShortWeekday: (locale: string | undefined, date: Date) => string = getSafeFormatter(formatShortWeekdayOptions); export const formatWeekday: (locale: string | undefined, date: Date) => string = getSafeFormatter(formatWeekdayOptions); export const formatYear: (locale: string | undefined, date: Date) => string = getSafeFormatter(formatYearOptions);