diff --git a/src/helpers/date-jalali.ts b/src/helpers/date-jalali.ts index cb1eeb9..a618255 100644 --- a/src/helpers/date-jalali.ts +++ b/src/helpers/date-jalali.ts @@ -96,14 +96,13 @@ function jalaliPartsToGregorian( jMonth: number, jDay: number, ): string | null { - // Jalali to Julian Day Number, then to Gregorian - // Algorithm: https://www.fourmilab.ch/documents/calendar/ const jy = jYear - 979; const jm = jMonth - 1; const jd = jDay - 1; + // Jalali day number — correct leap cycle is every 33 years with 8 leaps let jDayNo = - 365 * jy + Math.floor(jy / 4) - Math.floor(jy / 100) + Math.floor(jy / 400); + 365 * jy + Math.floor(jy / 33) * 8 + Math.floor(((jy % 33) + 3) / 4); const jalaliMonthDays = [31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 29]; for (let i = 0; i < jm; i++) { @@ -111,29 +110,29 @@ function jalaliPartsToGregorian( } jDayNo += jd; - // Convert to Gregorian day number (offset from 1970-01-01 in Julian days) - const gDayNo = jDayNo + 79; + // Offset to Gregorian day number anchored at 1600 + let gDayNo = jDayNo + 79; - let gy = 1979 + 400 * Math.floor(gDayNo / 146097); - let days = gDayNo % 146097; + let gy = 1600 + 400 * Math.floor(gDayNo / 146097); + gDayNo %= 146097; let leap = true; - if (days >= 36525) { - days--; - gy += 100 * Math.floor(days / 36524); - days %= 36524; - if (days >= 365) days++; + if (gDayNo >= 36525) { + gDayNo--; + gy += 100 * Math.floor(gDayNo / 36524); + gDayNo %= 36524; + if (gDayNo >= 365) gDayNo++; else leap = false; } - gy += 4 * Math.floor(days / 1461); - days %= 1461; + gy += 4 * Math.floor(gDayNo / 1461); + gDayNo %= 1461; - if (days >= 366) { + if (gDayNo >= 366) { leap = false; - days--; - gy += Math.floor(days / 365); - days %= 365; + gDayNo--; + gy += Math.floor(gDayNo / 365); + gDayNo %= 365; } const gregorianMonthDays = [ @@ -153,19 +152,18 @@ function jalaliPartsToGregorian( let gm = 0; for (let i = 0; i < 12; i++) { - if (days < gregorianMonthDays[i]) { + if (gDayNo < gregorianMonthDays[i]) { gm = i + 1; break; } - days -= gregorianMonthDays[i]; + gDayNo -= gregorianMonthDays[i]; } - const gd = days + 1; + const gd = gDayNo + 1; const mm = String(gm).padStart(2, "0"); const dd = String(gd).padStart(2, "0"); const result = `${gy}-${mm}-${dd}`; - // Sanity check const check = new Date(result); if (isNaN(check.getTime())) return null; diff --git a/src/sand-hub/sand-hub.service.ts b/src/sand-hub/sand-hub.service.ts index 801cb07..b156e41 100644 --- a/src/sand-hub/sand-hub.service.ts +++ b/src/sand-hub/sand-hub.service.ts @@ -564,6 +564,7 @@ export class SandHubService { const requestUrl = `${process.env.SANHUB_BASE_URL}/personal-inquiry/tejarat-no`; const gregorianBirthdate = jalaliToGregorianDate(birthDate); + console.log(gregorianBirthdate); if (!gregorianBirthdate) { throw new BadRequestException( `Invalid birth date for personal inquiry: ${birthDate}. Expected a Jalali date (e.g. 13770624 or "1377-06-24").`,