AbdulElahGwaith's picture
Upload folder using huggingface_hub
cf86710 verified
import type { FormatOptions as DateFnsFormatOptions } from "date-fns";
import type { DateLibOptions } from "../../classes/DateLib.js";
import { toEthiopicDate } from "../utils/index.js";
import { formatNumber } from "./formatNumber.js";
/** Options for formatting dates in the Ethiopian calendar */
export type FormatOptions = DateFnsFormatOptions;
function getEtDayName(
day: Date,
short: boolean = true,
localeCode: string = "am-ET",
): string {
try {
const dtf = new Intl.DateTimeFormat(localeCode, {
// Ethiopic calendar expects single-letter for "cccccc" -> use narrow
weekday: short ? ("narrow" as const) : ("long" as const),
});
return dtf.format(day);
} catch {
const dayOfWeek = day.getDay();
return short ? shortDays[dayOfWeek] : longDays[dayOfWeek];
}
}
function getEtMonthName(m: number, latin = false): string {
if (m > 0 && m <= 13) {
return latin ? ethMonthsLatin[m - 1] : ethMonths[m - 1];
}
return "";
}
function formatEthiopianDate(
dateObj: Date | undefined,
formatStr: string,
numerals?: DateLibOptions["numerals"],
localeCode?: string,
): string {
const etDate = dateObj ? toEthiopicDate(dateObj) : undefined;
if (!etDate) return "";
const useLatin =
(localeCode?.startsWith("en") ?? false) || numerals === "latn";
const yearTokenMatch = formatStr.match(/^(\s*)(y+)(\s*)$/);
if (yearTokenMatch) {
const [, leading = "", yearToken, trailing = ""] = yearTokenMatch;
const year = etDate.year.toString();
let formattedYear: string;
if (yearToken.length === 1) {
formattedYear = year;
} else if (yearToken.length === 2) {
formattedYear = year.slice(-2).padStart(2, "0");
} else {
formattedYear = year.padStart(yearToken.length, "0");
}
return `${leading}${formattedYear}${trailing}`;
}
switch (formatStr) {
case "LLLL yyyy":
case "LLLL y":
return `${getEtMonthName(etDate.month, useLatin)} ${etDate.year}`;
case "LLLL":
return getEtMonthName(etDate.month, useLatin);
case "yyyy-MM-dd":
return `${etDate.year}-${etDate.month
.toString()
.padStart(2, "0")}-${etDate.day.toString().padStart(2, "0")}`;
case "yyyy-MM":
return `${etDate.year}-${etDate.month.toString().padStart(2, "0")}`;
case "d":
return etDate.day.toString();
case "PPP":
return ` ${getEtMonthName(etDate.month, useLatin)} ${etDate.day}, ${etDate.year}`;
case "PPPP":
if (!dateObj) return "";
return `${getEtDayName(dateObj, false, localeCode)}, ${getEtMonthName(etDate.month, useLatin)} ${
etDate.day
}, ${etDate.year}`;
case "cccc":
return dateObj ? getEtDayName(dateObj, false, localeCode) : "";
case "cccccc":
return dateObj ? getEtDayName(dateObj, true, localeCode) : "";
default:
return `${etDate.day}/${etDate.month}/${etDate.year}`;
}
}
/**
* Format an Ethiopic calendar date using a subset of date-fns tokens.
*
* Behavior specifics for Ethiopic mode:
*
* - Weekday names ("cccc", "cccccc") come from `Intl.DateTimeFormat` using
* `options.locale?.code` (default: `am-ET`). Narrow form is a single letter.
* - Month names ("LLLL") are Amharic by default and switch to Latin
* transliteration when the locale code starts with `en` or when
* `options.numerals === 'latn'`.
* - Time parts such as `hh:mm a` are delegated to `Intl.DateTimeFormat` with the
* given locale.
* - Digits are converted to Ethiopic (Geez) when `options.numerals === 'geez'`.
*/
export function format(
date: Date,
formatStr: string,
options?: DateFnsFormatOptions,
): string {
const extendedOptions = options as DateLibOptions;
if (formatStr.includes("hh:mm") || formatStr.includes("a")) {
return new Intl.DateTimeFormat(extendedOptions?.locale?.code ?? "en-US", {
hour: "numeric",
minute: "numeric",
hour12: formatStr.includes("a"),
}).format(date);
}
const formatted = formatEthiopianDate(
date,
formatStr,
extendedOptions?.numerals,
extendedOptions?.locale?.code ?? "am-ET",
);
if (extendedOptions?.numerals && extendedOptions.numerals === "geez") {
return formatted.replace(/\d+/g, (match) =>
formatNumber(parseInt(match, 10), "geez"),
);
}
return formatted;
}
export const ethMonths = [
"መሡከረም",
"αŒ₯α‰…αˆα‰΅",
"αˆ…α‹³αˆ­",
"α‰³αˆ…αˆ³αˆ΅",
"αŒ₯ር",
"α‹¨αŠ«α‰²α‰΅",
"αˆ˜αŒ‹α‰’α‰΅",
"αˆšα‹«α‹šα‹«",
"αŒαŠ•α‰¦α‰΅",
"αˆ°αŠ”",
"ሐምሌ",
"αŠαˆ€αˆ΄",
"αŒ³αŒ‰αˆœ",
];
export const ethMonthsLatin = [
"Meskerem",
"Tikimt",
"Hidar",
"Tahsas",
"Tir",
"Yekatit",
"Megabit",
"Miyazya",
"Ginbot",
"Sene",
"Hamle",
"Nehase",
"Pagumen",
];
export const shortDays = ["αŠ₯", "ሰ", "αˆ›", "ረ", "ሐ", "α‹“", "α‰…"];
export const longDays = ["αŠ₯αˆα‹΅", "ሰኞ", "αˆ›αŠ­αˆ°αŠž", "αˆ¨α‰‘α‹•", "αˆαˆ™αˆ΅", "α‹“αˆ­α‰₯", "α‰…α‹³αˆœ"];