/** کلید روز (YYYY-MM-DD) و زمان‌ها همگی به وقت تهران (بدون ساعت تابستانی، +03:30). */ export const TEHRAN_OFFSET = '+03:30'; const DAY_FMT = new Intl.DateTimeFormat('en-CA', { timeZone: 'Asia/Tehran', year: 'numeric', month: '2-digit', day: '2-digit', }); const HOUR_FMT = new Intl.DateTimeFormat('en-US', { timeZone: 'Asia/Tehran', hour: '2-digit', hourCycle: 'h23', }); const JALALI_DAY_FMT = new Intl.DateTimeFormat('en-US-u-ca-persian', { timeZone: 'UTC', day: 'numeric', }); const DAY_KEY_RE = /^\d{4}-\d{2}-\d{2}$/; const TIME_RE = /^([01]\d|2[0-3]):[0-5]\d$/; export function isDayKey(value: unknown): value is string { return typeof value === 'string' && DAY_KEY_RE.test(value); } export function isTimeOfDay(value: unknown): value is string { return typeof value === 'string' && TIME_RE.test(value); } export function tehranDayKey(d: Date = new Date()): string { return DAY_FMT.format(d); } export function tehranHour(d: Date = new Date()): number { return Number(HOUR_FMT.format(d)) % 24; } /** مقدار مناسب برای ستون‌های @db.Date */ export function dayKeyToDate(key: string): Date { return new Date(`${key}T00:00:00.000Z`); } /** خواندن ستون‌های @db.Date */ export function dateToDayKey(d: Date): string { return d.toISOString().slice(0, 10); } export function addDays(key: string, n: number): string { const d = dayKeyToDate(key); d.setUTCDate(d.getUTCDate() + n); return dateToDayKey(d); } /** b - a بر حسب روز */ export function dayDiff(a: string, b: string): number { return Math.round( (dayKeyToDate(b).getTime() - dayKeyToDate(a).getTime()) / 86_400_000, ); } /** ۰ = شنبه … ۶ = جمعه */ export function persianWeekday(key: string): number { return (dayKeyToDate(key).getUTCDay() + 1) % 7; } /** شنبهٔ همان هفته */ export function weekStartKey(key: string): string { return addDays(key, -persianWeekday(key)); } export function jalaliDayOfMonth(key: string): number { return Number(JALALI_DAY_FMT.format(dayKeyToDate(key))); } export function tehranDateTime(key: string, hhmm: string): Date { return new Date(`${key}T${hhmm}:00${TEHRAN_OFFSET}`); } export function tehranDayStart(key: string): Date { return tehranDateTime(key, '00:00'); } export function eachDay(from: string, to: string): string[] { const out: string[] = []; let cur = from; let guard = 0; while (cur <= to && guard < 800) { out.push(cur); cur = addDays(cur, 1); guard += 1; } return out; } export function toFaDigits(value: number | string): string { return String(value).replace(/\d/g, (d) => '۰۱۲۳۴۵۶۷۸۹'[Number(d)]!); }