File size: 5,136 Bytes
cf86710 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 | import type { FormatOptions as DateFnsFormatOptions } from "date-fns";
import type { DateLibOptions } from "../../classes/DateLib.js";
import { getMonthCode } from "../utils/calendarMath.js";
import { toHebrewDate } from "../utils/dateConversion.js";
import { hebrewMonthNumber } from "../utils/serial.js";
const fallbackMonthNames: Record<string, { en: string; he: string }> = {
tishrei: { en: "Tishrei", he: "转砖专讬" },
cheshvan: { en: "Cheshvan", he: "讞砖讜讜谉" },
kislev: { en: "Kislev", he: "讻住诇讜" },
tevet: { en: "Tevet", he: "讟讘转" },
shevat: { en: "Shevat", he: "砖讘讟" },
adarI: { en: "Adar I", he: "讗讚专 讗壮" },
adar: { en: "Adar", he: "讗讚专" },
nisan: { en: "Nisan", he: "谞讬住谉" },
iyar: { en: "Iyar", he: "讗讬讬专" },
sivan: { en: "Sivan", he: "住讬讜讜谉" },
tamuz: { en: "Tammuz", he: "转诪讜讝" },
av: { en: "Av", he: "讗讘" },
elul: { en: "Elul", he: "讗诇讜诇" },
};
const fallbackWeekdayNames = {
long: {
en: [
"Sunday",
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday",
],
he: [
"讬讜诐 专讗砖讜谉",
"讬讜诐 砖谞讬",
"讬讜诐 砖诇讬砖讬",
"讬讜诐 专讘讬注讬",
"讬讜诐 讞诪讬砖讬",
"讬讜诐 砖讬砖讬",
"砖讘转",
],
},
narrow: {
en: ["S", "M", "T", "W", "T", "F", "S"],
he: ["讗", "讘", "讙", "讚", "讛", "讜", "砖"],
},
};
const getLocaleCode = (options?: DateLibOptions): string => {
return options?.locale?.code ?? "he";
};
const getMonthCodeForDate = (date: Date) => {
const hebrew = toHebrewDate(date);
return getMonthCode(hebrew.year, hebrew.monthIndex);
};
const formatMonthName = (date: Date, localeCode: string): string => {
try {
return new Intl.DateTimeFormat(localeCode, {
month: "long",
calendar: "hebrew",
}).format(date);
} catch {
const code = getMonthCodeForDate(date);
const isHebrew = localeCode.startsWith("he");
return isHebrew ? fallbackMonthNames[code].he : fallbackMonthNames[code].en;
}
};
const formatWeekdayName = (
date: Date,
localeCode: string,
width: "long" | "narrow",
): string => {
try {
return new Intl.DateTimeFormat(localeCode, {
weekday: width,
calendar: "hebrew",
}).format(date);
} catch {
const index = date.getDay();
const isHebrew = localeCode.startsWith("he");
return isHebrew
? fallbackWeekdayNames[width].he[index]
: fallbackWeekdayNames[width].en[index];
}
};
const formatDateStyle = (
date: Date,
localeCode: string,
style: "long" | "full",
): string => {
try {
return new Intl.DateTimeFormat(localeCode, {
dateStyle: style,
calendar: "hebrew",
}).format(date);
} catch {
const hebrew = toHebrewDate(date);
const month = formatMonthName(date, localeCode);
if (style === "full") {
const weekday = formatWeekdayName(date, localeCode, "long");
return `${weekday}, ${month} ${hebrew.day}, ${hebrew.year}`;
}
return `${month} ${hebrew.day}, ${hebrew.year}`;
}
};
const formatNumber = (value: number): string => {
return value.toString();
};
const buildTimeFormat = (
date: Date,
localeCode: string,
formatStr: string,
): string => {
const hour12 = formatStr.includes("a");
return new Intl.DateTimeFormat(localeCode, {
hour: "numeric",
minute: "numeric",
hour12,
}).format(date);
};
/** Hebrew calendar formatting override. */
export function format(
date: Date,
formatStr: string,
options?: DateFnsFormatOptions,
): string {
const extendedOptions = options as DateLibOptions | undefined;
const localeCode = getLocaleCode(extendedOptions);
const hebrew = toHebrewDate(date);
const monthNumber = hebrewMonthNumber(hebrew.monthIndex);
switch (formatStr) {
case "LLLL y":
case "LLLL yyyy":
return `${formatMonthName(date, localeCode)} ${formatNumber(hebrew.year)}`;
case "LLLL":
return formatMonthName(date, localeCode);
case "PPP":
return formatDateStyle(date, localeCode, "long");
case "PPPP":
return formatDateStyle(date, localeCode, "full");
case "cccc":
return formatWeekdayName(date, localeCode, "long");
case "cccccc":
return formatWeekdayName(date, localeCode, "narrow");
case "yyyy":
case "y":
return formatNumber(hebrew.year);
case "yyyy-MM":
return `${formatNumber(hebrew.year)}-${formatNumber(monthNumber).padStart(2, "0")}`;
case "yyyy-MM-dd":
return `${formatNumber(hebrew.year)}-${formatNumber(monthNumber).padStart(2, "0")}-${formatNumber(hebrew.day).padStart(2, "0")}`;
case "MM":
return formatNumber(monthNumber).padStart(2, "0");
case "M":
return formatNumber(monthNumber);
case "dd":
return formatNumber(hebrew.day).padStart(2, "0");
case "d":
return formatNumber(hebrew.day);
default:
if (/[Hh]/.test(formatStr) && /m/.test(formatStr)) {
return buildTimeFormat(date, localeCode, formatStr);
}
return `${formatNumber(hebrew.day)}/${formatNumber(monthNumber)}/${formatNumber(hebrew.year)}`;
}
}
|