import { jalaaliMonthLength, toGregorian, toJalaali } from 'jalaali-js' const persianDigits = '۰۱۲۳۴۵۶۷۸۹' function toPersianDigits(input: string): string { return input.replace(/\d/g, (d) => persianDigits[Number(d)]!) } export const JALALI_MONTH_NAMES = [ 'فروردین', 'اردیبهشت', 'خرداد', 'تیر', 'مرداد', 'شهریور', 'مهر', 'آبان', 'آذر', 'دی', 'بهمن', 'اسفند', ] as const export const JALALI_WEEKDAY_NAMES = ['ش', 'ی', 'د', 'س', 'چ', 'پ', 'ج'] as const export interface JalaliDate { jy: number jm: number jd: number } export function parseISODate(iso: string): Date { const match = iso.trim().match(/^(\d{4})-(\d{2})-(\d{2})/) if (match) { return new Date(Number(match[1]), Number(match[2]) - 1, Number(match[3])) } const parsed = new Date(iso) if (Number.isNaN(parsed.getTime())) { return new Date(NaN) } return new Date(parsed.getFullYear(), parsed.getMonth(), parsed.getDate()) } export function toISODate(date: Date): string { const year = date.getFullYear() const month = String(date.getMonth() + 1).padStart(2, '0') const day = String(date.getDate()).padStart(2, '0') return `${year}-${month}-${day}` } export function toJalali(date: Date): JalaliDate { const { jy, jm, jd } = toJalaali(date.getFullYear(), date.getMonth() + 1, date.getDate()) return { jy, jm, jd } } export function fromJalali(jy: number, jm: number, jd: number): Date { const { gy, gm, gd } = toGregorian(jy, jm, jd) return new Date(gy, gm - 1, gd) } export function isoToJalali(iso: string): JalaliDate | null { if (!iso) return null return toJalali(parseISODate(iso)) } export function jalaliToISO(jy: number, jm: number, jd: number): string { return toISODate(fromJalali(jy, jm, jd)) } export function formatJalaliDate(jy: number, jm: number, jd: number): string { const month = String(jm).padStart(2, '0') const day = String(jd).padStart(2, '0') return toPersianDigits(`${jy}/${month}/${day}`) } export function formatJalaliLabel(jy: number, jm: number, jd: number): string { return `${toPersianDigits(String(jd))} ${JALALI_MONTH_NAMES[jm - 1]} ${toPersianDigits(String(jy))}` } export function getPersianWeekday(jy: number, jm: number, jd: number): number { const { gy, gm, gd } = toGregorian(jy, jm, jd) const jsDay = new Date(gy, gm - 1, gd).getDay() return (jsDay + 1) % 7 } export function getMonthLength(jy: number, jm: number): number { return jalaaliMonthLength(jy, jm) } export function buildCalendarDays(jy: number, jm: number): Array { const length = getMonthLength(jy, jm) const startWeekday = getPersianWeekday(jy, jm, 1) const cells: Array = Array.from({ length: startWeekday }, () => null) for (let day = 1; day <= length; day += 1) { cells.push(day) } while (cells.length % 7 !== 0) { cells.push(null) } return cells } export function todayJalali(): JalaliDate { return toJalali(new Date()) }