fix: stop birth dates from saving one day early in Tehran time
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -206,9 +206,7 @@ async function saveEdit() {
|
||||
region: editForm.value.region.trim() || null,
|
||||
source: editForm.value.source.trim() || null,
|
||||
instagram: editForm.value.instagram.trim() || null,
|
||||
birthDate: editForm.value.birthDate
|
||||
? (parseLocalInput(editForm.value.birthDate)?.toISOString() ?? null)
|
||||
: null,
|
||||
birthDate: editForm.value.birthDate || null,
|
||||
trade: editForm.value.trade.trim() || null,
|
||||
notes: editForm.value.notes.trim() || null,
|
||||
});
|
||||
|
||||
@@ -36,7 +36,7 @@ import {
|
||||
import { api } from '@/lib/api';
|
||||
import type { CompanyDto, CreatePersonRequest, PersonDto, PersonMood } from '@mento/shared';
|
||||
import { PERSON_MOOD_LABELS, PERSON_MOODS } from '@/lib/person-mood';
|
||||
import { formatLocalDateInput, parseLocalInput, toFaDigits } from '@/lib/jalali';
|
||||
import { formatLocalDateInput, toFaDigits } from '@/lib/jalali';
|
||||
import JalaliDateInput from '@/components/JalaliDateInput.vue';
|
||||
import {
|
||||
filterPhoneContacts,
|
||||
@@ -327,7 +327,7 @@ function payload(): CreatePersonRequest {
|
||||
position: position.value || undefined,
|
||||
website: website.value || undefined,
|
||||
instagram: instagram.value || undefined,
|
||||
birthDate: birthDate.value ? parseLocalInput(birthDate.value)?.toISOString() ?? null : null,
|
||||
birthDate: birthDate.value || null,
|
||||
referrer: referrer.value || undefined,
|
||||
addresses: addresses.value.map((a) => a.trim()).filter(Boolean),
|
||||
notes: notes.value || undefined,
|
||||
|
||||
Reference in New Issue
Block a user