|
| 1 | +/* |
| 2 | +Source: https://github.com/SCR-IR/tarikh-npm |
| 3 | +*/ |
| 4 | + |
| 5 | +.pragma library |
| 6 | + |
| 7 | +Qt.hijriDate = (function () { |
| 8 | + const COUNTRY = 'IR'; |
| 9 | + |
| 10 | + function fromGregorian(year, month, day) { |
| 11 | + [year, month, day] = _gregorianToHijri(parseInt(year), parseInt(month), parseInt(day)); |
| 12 | + return { year, month, day }; |
| 13 | + } |
| 14 | + |
| 15 | + function toGregorian(year, month, day) { |
| 16 | + [year, month, day] = _hijriToGregorian(parseInt(year), parseInt(month), parseInt(day)); |
| 17 | + return { year, month, day }; |
| 18 | + } |
| 19 | + |
| 20 | + function _gregorianToHijri(gY, gM, gD) { |
| 21 | + return _julianDayToHijri(_gregorianToJulianDay(gY, gM, gD)); |
| 22 | + } |
| 23 | + |
| 24 | + function _hijriToGregorian(iY, iM, iD) { |
| 25 | + return _julianDayToGregorian(_hijriToJulianDay(iY, iM, iD)); |
| 26 | + } |
| 27 | + |
| 28 | + function _gregorianToJulianDay(gY, gM, gD) { |
| 29 | + let gDoM, gY2, julianDay; |
| 30 | + gDoM = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334]; |
| 31 | + gY2 = gM > 2 ? gY + 1 : gY; |
| 32 | + julianDay = |
| 33 | + 1721059 + 365 * gY + ~~((gY2 + 3) / 4) - ~~((gY2 + 99) / 100) + ~~((gY2 + 399) / 400) + gD + gDoM[gM - 1]; |
| 34 | + /* 1721059 = _gregorianToJulianDay(0, 1, 1) - 1 */ |
| 35 | + return julianDay; |
| 36 | + } |
| 37 | + |
| 38 | + function _julianDayToGregorian(julianDay) { |
| 39 | + let days, gD, gDoM, gM, gY; |
| 40 | + days = -~~(1721060 - julianDay); |
| 41 | + gY = 400 * ~~(days / 146097); |
| 42 | + days %= 146097; |
| 43 | + if (days > 36524) { |
| 44 | + gY += 100 * ~~(--days / 36524); |
| 45 | + days %= 36524; |
| 46 | + if (days >= 365) { |
| 47 | + days++; |
| 48 | + } |
| 49 | + } |
| 50 | + gY += 4 * ~~(days / 1461); |
| 51 | + days %= 1461; |
| 52 | + if (days > 365) { |
| 53 | + gY += ~~((days - 1) / 365); |
| 54 | + days = (days - 1) % 365; |
| 55 | + } |
| 56 | + gD = days + 1; |
| 57 | + gDoM = [ |
| 58 | + 0, |
| 59 | + 31, |
| 60 | + (gY % 4 === 0 && gY % 100 !== 0) || gY % 400 === 0 ? 29 : 28, |
| 61 | + 31, |
| 62 | + 30, |
| 63 | + 31, |
| 64 | + 30, |
| 65 | + 31, |
| 66 | + 31, |
| 67 | + 30, |
| 68 | + 31, |
| 69 | + 30, |
| 70 | + 31, |
| 71 | + ]; |
| 72 | + for (gM = 0; gM < 13 && gD > gDoM[gM]; gM++) { |
| 73 | + gD -= gDoM[gM]; |
| 74 | + } |
| 75 | + |
| 76 | + return [gY, gM, gD]; |
| 77 | + } |
| 78 | + |
| 79 | + function _hijriAToJulianDay(iy, im, id) { |
| 80 | + iy += 990; |
| 81 | + return ~~(id + ~~(29.5 * (im - 1) + 0.5) + (iy - 1) * 354 + ~~((3 + iy * 11) / 30) + 1597616); |
| 82 | + } |
| 83 | + |
| 84 | + function _julianDayToHijriA(julianDay) { |
| 85 | + let id, im, iy, tmp; |
| 86 | + julianDay = ~~julianDay + 350822.5; // 350823d=990y |
| 87 | + iy = ~~((30 * (julianDay - 1948439.5) + 10646) / 10631); |
| 88 | + tmp = julianDay - (1948439.5 + (iy - 1) * 354 + ~~((3 + 11 * iy) / 30)); |
| 89 | + iy -= 990; |
| 90 | + im = ~~((tmp - 29) / 29.5 + 1.99); |
| 91 | + if (im > 12) { |
| 92 | + im = 12; |
| 93 | + } |
| 94 | + |
| 95 | + id = 1 + tmp - ~~(29.5 * (im - 1) + 0.5); |
| 96 | + return [iy, im, id]; |
| 97 | + } |
| 98 | + |
| 99 | + function _hijriToJulianDay(iY, iM, iD) { |
| 100 | + const HILAL = _hilalIM(COUNTRY); |
| 101 | + if (iY < HILAL.startYear || iY > HILAL.endYear) { |
| 102 | + return _hijriAToJulianDay(iY, iM, iD); |
| 103 | + } |
| 104 | + |
| 105 | + let julianDay = HILAL.startJD - 1 + iD; |
| 106 | + for (let y in HILAL.iDoM) { |
| 107 | + if (y < iY) { |
| 108 | + julianDay += HILAL.iDoM[y][0]; |
| 109 | + } else { |
| 110 | + for (let m = 1; m < iM; m++) { |
| 111 | + julianDay += HILAL.iDoM[iY][m]; |
| 112 | + } |
| 113 | + |
| 114 | + break; |
| 115 | + } |
| 116 | + } |
| 117 | + return julianDay; |
| 118 | + } |
| 119 | + |
| 120 | + function _julianDayToHijri(julianDay) { |
| 121 | + const HILAL = _hilalIM(COUNTRY); |
| 122 | + if (julianDay < HILAL.startJD || julianDay > HILAL.endJD) { |
| 123 | + return _julianDayToHijriA(julianDay); |
| 124 | + } |
| 125 | + |
| 126 | + let iM, iY; |
| 127 | + let iD = julianDay - HILAL.startJD + 1; |
| 128 | + for (iY in HILAL.iDoM) { |
| 129 | + if (iD > HILAL.iDoM[iY][0]) { |
| 130 | + iD -= HILAL.iDoM[iY][0]; |
| 131 | + } else { |
| 132 | + for (iM = 1; iM < 13 && iD > HILAL.iDoM[iY][iM]; iM++) { |
| 133 | + iD -= HILAL.iDoM[iY][iM]; |
| 134 | + } |
| 135 | + |
| 136 | + break; |
| 137 | + } |
| 138 | + } |
| 139 | + return [Number(iY), iM, ~~iD]; |
| 140 | + } |
| 141 | + |
| 142 | + function _hilalIM(country = 'IR') { |
| 143 | + return { |
| 144 | + IR: { |
| 145 | + startYear: 1427 /* =iDoM:firstYear */, |
| 146 | + startJD: 2453767 /* =_hijriAToJulianDay(startYear,1,1) */, |
| 147 | + |
| 148 | + endYear: 1464 /* =iDoM:lastYear */, |
| 149 | + endJD: 2467232 /* =_hijriAToJulianDay(endYear+1,1,1)-1 */, |
| 150 | + |
| 151 | + iDoM: { |
| 152 | + // islamicYear: [Sum, m1, ..., m12], |
| 153 | + 1427: [355, 30, 29, 29, 30, 29, 30, 30, 30, 30, 29, 29, 30], |
| 154 | + 1428: [354, 29, 30, 29, 29, 29, 30, 30, 29, 30, 30, 30, 29], |
| 155 | + 1429: [354, 30, 29, 30, 29, 29, 29, 30, 30, 29, 30, 30, 29], |
| 156 | + 1430: [354, 30, 30, 29, 29, 30, 29, 30, 29, 29, 30, 30, 29], |
| 157 | + 1431: [354, 30, 30, 29, 30, 29, 30, 29, 30, 29, 29, 30, 29], |
| 158 | + 1432: [355, 30, 30, 29, 30, 30, 30, 29, 29, 30, 29, 30, 29], |
| 159 | + 1433: [355, 29, 30, 29, 30, 30, 30, 29, 30, 29, 30, 29, 30], |
| 160 | + 1434: [354, 29, 29, 30, 29, 30, 30, 29, 30, 30, 29, 30, 29], |
| 161 | + 1435: [355, 29, 30, 29, 30, 29, 30, 29, 30, 30, 30, 29, 30], |
| 162 | + 1436: [354, 29, 30, 29, 29, 30, 29, 30, 29, 30, 29, 30, 30], |
| 163 | + 1437: [354, 29, 30, 30, 29, 30, 29, 29, 30, 29, 29, 30, 30], |
| 164 | + 1438: [354, 29, 30, 30, 30, 29, 30, 29, 29, 30, 29, 29, 30], |
| 165 | + 1439: [354, 29, 30, 30, 30, 30, 29, 30, 29, 29, 30, 29, 29], |
| 166 | + 1440: [355, 30, 29, 30, 30, 30, 29, 30, 30, 29, 29, 30, 29], |
| 167 | + 1441: [355, 29, 30, 29, 30, 30, 29, 30, 30, 29, 30, 29, 30], |
| 168 | + 1442: [354, 29, 29, 30, 29, 30, 29, 30, 30, 29, 30, 30, 29], |
| 169 | + 1443: [354, 29, 30, 30, 29, 29, 30, 29, 30, 30, 29, 30, 29], |
| 170 | + 1444: [354, 30, 30, 29, 30, 29, 29, 30, 29, 30, 29, 30, 29], |
| 171 | + 1445: [ |
| 172 | + 355, 30, 30, 30, 29, 30, 29, 29, 30 /* :1402_Official_Iranian_Calendar and Temporary_1403: */, 29, 30, 29, |
| 173 | + 30, |
| 174 | + ], |
| 175 | + 1446: [354, 29, 30, 29, 30, 30, 30, 29, 30, 29, 29, 30, 29], |
| 176 | + 1447: [355, 29, 30, 29, 30, 30, 30, 29, 30, 30, 29, 29, 30], |
| 177 | + 1448: [354, 29, 29, 30, 29, 30, 30, 29, 30, 30, 30, 29, 29], |
| 178 | + 1449: [355, 30, 29, 29, 30, 29, 30, 29, 30, 30, 30, 29, 30], |
| 179 | + 1450: [354, 29, 30, 29, 29, 30, 29, 30, 29, 30, 30, 30, 29], |
| 180 | + 1451: [354, 30, 29, 30, 29, 29, 30, 29, 30, 29, 30, 30, 29], |
| 181 | + 1452: [354, 30, 30, 29, 30, 29, 29, 30, 29, 30, 29, 30, 29], |
| 182 | + 1453: [355, 30, 30, 29, 30, 29, 30, 30, 29, 29, 30, 29, 30], |
| 183 | + 1454: [354, 29, 30, 29, 30, 30, 29, 30, 30, 29, 30, 29, 29], |
| 184 | + 1455: [355, 30, 29, 30, 29, 30, 29, 30, 30, 29, 30, 30, 29], |
| 185 | + 1456: [355, 29, 30, 29, 29, 30, 29, 30, 30, 29, 30, 30, 30], |
| 186 | + 1457: [354, 29, 29, 30, 29, 29, 30, 29, 30, 29, 30, 30, 30], |
| 187 | + 1458: [354, 30, 29, 29, 30, 29, 29, 30, 29, 30, 29, 30, 30], |
| 188 | + 1459: [354, 30, 29, 30, 29, 30, 29, 29, 30, 29, 30, 29, 30], |
| 189 | + 1460: [354, 30, 29, 30, 30, 29, 30, 29, 29, 30, 29, 30, 29], |
| 190 | + 1461: [355, 30, 29, 30, 30, 29, 30, 30, 29, 29, 30, 29, 30], |
| 191 | + 1462: [354, 29, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30, 29], |
| 192 | + 1463: [355, 30, 29, 30, 29, 30, 29, 30, 29, 30, 30, 29, 30], |
| 193 | + 1464: [ |
| 194 | + 354 /* : 355|354 <- Sum <- */, 30, 29, 29, 30, 29, 29, 30, 29, 30, 30, 29, |
| 195 | + 30 /* : 30|29 -> verify -> true */, |
| 196 | + ], |
| 197 | + /* |
| 198 | + verify = ( (endJD - _hijriAToJulianDay(endYear,12,iDoM[endYear][12])) === 0 ); |
| 199 | + */ |
| 200 | + }, |
| 201 | + }, |
| 202 | + }[country]; |
| 203 | + } |
| 204 | + |
| 205 | + return { |
| 206 | + fromGregorian, |
| 207 | + }; |
| 208 | +})(); |
0 commit comments