fix: stop birth dates from saving one day early in Tehran time

This commit is contained in:
2026-10-20 15:20:47 +03:30
parent 9a86f63f48
commit 9127fa334b
3 changed files with 28 additions and 5 deletions
+25
View File
@@ -170,9 +170,34 @@ export function parseAmount(raw?: string): number | null {
}
/** تاریخ تولد: سال زیر ۱۷۰۰ شمسی است، سال ۱۷۰۰ به بعد میلادی. ظهر UTC تا روز جابه‌جا نشود. */
/** «۲۰۲۴-۰۵-۰۱T۱۹:۳۰:۰۰Z» و مشابه: لحظهٔ دقیق با منطقهٔ زمانی */
const ZONED_TIMESTAMP = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}(:\d{2}(\.\d+)?)?(Z|[+-]\d{2}:?\d{2})$/i;
function tehranCalendarDay(d: Date): { y: number; m: number; d: number } {
const [y, m, day] = new Intl.DateTimeFormat('en-CA', {
timeZone: 'Asia/Tehran',
year: 'numeric',
month: '2-digit',
day: '2-digit',
})
.format(d)
.split('-')
.map(Number);
return { y, m, d: day };
}
export function parseBirthDate(raw?: string | null): Date | null {
const text = toAsciiDigits(String(raw ?? '')).trim();
if (!text || text === '-' || text === '0' || text === '0000-00-00') return null;
// تاریخ تولد فقط «روز» است. لحظهٔ UTC (مثلاً نیمه‌شب تهران که به روز قبلِ UTC می‌افتد)
// باید با تقویم تهران به روز تبدیل شود، نه با بریدن بخش تاریخِ UTC.
if (ZONED_TIMESTAMP.test(text)) {
const instant = new Date(text);
if (!Number.isNaN(instant.getTime())) {
const day = tehranCalendarDay(instant);
return new Date(Date.UTC(day.y, day.m - 1, day.d, 12, 0, 0));
}
}
const datePart = text.split(/[T\s]/)[0] ?? text;
const match = /^(\d{3,4})[\/\-.](\d{1,2})[\/\-.](\d{1,2})$/.exec(datePart);
if (!match) {