UNPKG

react-day-picker

Version:

Customizable Date Picker for React

147 lines (146 loc) 5.41 kB
import { toHijriDate } from "../utils/conversion.js"; import { clampGregorianDate, getGregorianDateParts } from "../utils/range.js"; import { getFallbackMonthName, getFallbackWeekdayName, } from "./fallbackLocaleData.js"; const DEFAULT_LOCALE_CODE = "ar-SA"; const BASE_NUMBERING_SYSTEM = "latn"; const UMM_AL_QURA_CALENDAR = "islamic-umalqura"; const getLocaleCode = (options) => { return options?.locale?.code ?? DEFAULT_LOCALE_CODE; }; const formatWithUmmAlQura = (date, localeCode, options) => { try { return new Intl.DateTimeFormat(localeCode, { ...options, calendar: UMM_AL_QURA_CALENDAR, numberingSystem: BASE_NUMBERING_SYSTEM, }).format(date); } catch { return undefined; } }; const formatNumber = (value) => { return value.toString(); }; const formatPaddedNumber = (value) => { return formatNumber(value).padStart(2, "0"); }; const formatMonthName = (date, localeCode, width) => { const formatted = formatWithUmmAlQura(date, localeCode, { month: width, }); return formatted ?? getFallbackMonthName(date, localeCode, width); }; const formatWeekdayName = (date, localeCode, width) => { const formatted = formatWithUmmAlQura(date, localeCode, { weekday: width, }); return formatted ?? getFallbackWeekdayName(date, localeCode, width); }; const formatDateStyle = (date, localeCode, style) => { const formatted = formatWithUmmAlQura(date, localeCode, { dateStyle: style, }); if (formatted) { return formatted; } const hijri = toHijriDate(date); const monthName = getFallbackMonthName(date, localeCode, "long"); switch (style) { case "full": return `${getFallbackWeekdayName(date, localeCode, "long")}, ${monthName} ${hijri.day}, ${hijri.year}`; case "long": return `${monthName} ${hijri.day}, ${hijri.year}`; case "medium": return `${formatPaddedNumber(hijri.day)} ${monthName} ${hijri.year}`; case "short": return `${hijri.monthIndex + 1}/${hijri.day}/${hijri.year}`; } }; const buildTimeFormat = (date, localeCode, formatStr) => { const hour12 = formatStr.includes("a"); const formatted = formatWithUmmAlQura(date, localeCode, { hour: "numeric", minute: "numeric", hour12, }); if (formatted) { return formatted; } try { return new Intl.DateTimeFormat(localeCode, { hour: "numeric", minute: "numeric", hour12, numberingSystem: BASE_NUMBERING_SYSTEM, }).format(date); } catch { const minutes = formatPaddedNumber(date.getMinutes()); if (hour12) { const hour = date.getHours() % 12 || 12; const period = date.getHours() >= 12 ? "PM" : "AM"; return `${hour}:${minutes} ${period}`; } return `${formatNumber(date.getHours())}:${minutes}`; } }; /** Hijri calendar formatting override. */ export function format(date, formatStr, options) { const extendedOptions = options; const localeCode = getLocaleCode(extendedOptions); const hijri = toHijriDate(date); const gregorian = getGregorianDateParts(date); const isOutOfRange = clampGregorianDate(date) !== date; const numericDate = isOutOfRange ? { year: gregorian.year, monthIndex: gregorian.month - 1, day: gregorian.day, } : hijri; switch (formatStr) { case "LLLL y": case "LLLL yyyy": return `${formatMonthName(date, localeCode, "long")} ${formatNumber(numericDate.year)}`; case "LLLL": return formatMonthName(date, localeCode, "long"); case "LLL": return formatMonthName(date, localeCode, "short"); case "PPP": return formatDateStyle(date, localeCode, "long"); case "PPPP": return formatDateStyle(date, localeCode, "full"); case "PP": return formatDateStyle(date, localeCode, "medium"); case "P": return formatDateStyle(date, localeCode, "short"); case "cccc": return formatWeekdayName(date, localeCode, "long"); case "ccc": return formatWeekdayName(date, localeCode, "short"); case "ccccc": case "cccccc": return formatWeekdayName(date, localeCode, "narrow"); case "yyyy": case "y": return formatNumber(numericDate.year); case "yyyy-MM": return `${formatNumber(numericDate.year)}-${formatPaddedNumber(numericDate.monthIndex + 1)}`; case "yyyy-MM-dd": return `${formatNumber(numericDate.year)}-${formatPaddedNumber(numericDate.monthIndex + 1)}-${formatPaddedNumber(numericDate.day)}`; case "MM": return formatPaddedNumber(numericDate.monthIndex + 1); case "M": return formatNumber(numericDate.monthIndex + 1); case "dd": return formatPaddedNumber(numericDate.day); case "d": return formatNumber(numericDate.day); default: if (/[Hh]/.test(formatStr) && /m/.test(formatStr)) { return buildTimeFormat(date, localeCode, formatStr); } return formatDateStyle(date, localeCode, "medium"); } }