/** * محاسبات تقویمی باید مستقل از تایم‌زون سرور باشد؛ کانتینرها روی UTC اجرا می‌شوند. * ایران از ۱۴۰۱ تغییر ساعت تابستانی ندارد، پس آفست ثابت +۰۳:۳۰ درست است. */ const TEHRAN_OFFSET_MS = (3 * 60 + 30) * 60 * 1000; const DAY_MS = 24 * 60 * 60 * 1000; function utcStartOfDay(date: Date): Date { const d = new Date(date); d.setUTCHours(0, 0, 0, 0); return d; } /** * روز تقویمی تهرانِ یک لحظه را به‌صورت نیمه‌شب UTC همان روز برمی‌گرداند. * خروجی برای اختلاف‌گیری روزانه و سریال‌سازی `YYYY-MM-DD` امن است. */ export function tehranCalendarDay(date: Date): Date { return utcStartOfDay(new Date(date.getTime() + TEHRAN_OFFSET_MS)); } /** تاریخ سررسید فقط-روز است و نیمه‌شب UTC ذخیره می‌شود. */ export function calendarDayOf(date: Date | string): Date { return utcStartOfDay(new Date(date)); } export function addDays(date: Date, days: number): Date { return new Date(date.getTime() + days * DAY_MS); } export function diffInDays(from: Date, to: Date): number { return Math.round((to.getTime() - from.getTime()) / DAY_MS); } /** لحظه‌ای که در تهران ساعتِ داده‌شده از همان روزِ تقویمی است. */ export function tehranAtHour(date: Date, hour: number): Date { return new Date( tehranCalendarDay(date).getTime() + hour * 60 * 60 * 1000 - TEHRAN_OFFSET_MS, ); }