Pembaca, saya sudah keliling Google, membuka satu demi satu halaman hasil pencarian, tapi tidak juga menemukan rumus untuk menghitung kalender Hijriyah, baik konversi dari Masehi ataupun sebaliknya. Beberapa rumus dicoba, hasilnya tidak memuaskan. Untungnya, saat situs KalenderIndonesia.Com ini belum ada, saya sempat mendapatkan rumus perhitungan tersebut. Dan itu yang mendasari motivasi untuk mengembangkannya sehingga lahirlah situs ini. Walaupun rumus yang saya dapat tersebut belum cukup akurat, saya mencoba mengutak-atik sehingga berhasil menemukan racikan yang cukup memuaskan. Nah, berikut ini saya akan bocorkan rumus untuk menghitung kalender Hijriyah tersebut.
Sangkalan, rumus ini hanya untuk menghitung secara hisab Urfi, artinya hanya hitungan konvensional, tanpa memasukan parameter geo lainnya, seperti: garis lintang, garis bujur, ketinggian, zona waktu, dan lainnya. Rumus ini saya tulis menggunakan bahasa Typescript. Selamat menyimak!
function MasehiToHijri(year: number, month: number, day: number) { const intAW = 227016 const TA = [29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29] const JH = [0, 30, 59, 89, 118, 148, 177, 207, 236, 266, 295, 325, 354] const intMonth = month < 3 ? month + 12 : month const intYear = month < 3 ? year - 1 : year const intAM1 = Math.trunc(365.25 * intYear) + Math.trunc(30.60001 * (intMonth + 1)) + day - 428 const intB = intAM1 < 577748 ? 0 : 2 - Math.trunc(intYear / 100) + Math.trunc(Math.trunc(intYear / 100) / 4) const intAM = Math.trunc(365.25 * intYear) + Math.trunc(30.60001 * (intMonth + 1)) + day + intB - 428 const intAH = intAM - intAW const intThH1 = intAH / 354.3671 const intDayCount = Math.ceil(intAH % 354.367) const intAddYear = Math.trunc(intDayCount / 365) const intTHM2 = intThH1 + intAddYear + 1 const intSisa = intDayCount % 365 let intBulan1 = 0 for (let x = 1; x <= 12; x++) { if (intSisa >= JH[x - 1] && intSisa <= JH[x]) { intBulan1 = x - 1 break } } const intJmlHari = JH[intBulan1] let intSisaHari = intSisa - intJmlHari let yHijri = intTHM2 let mHijri = 0 if (intSisaHari >= 355) { intSisaHari = intSisaHari - intDayCount } let dHijri = intSisaHari if (intSisaHari === 0) { dHijri = 30 mHijri = 12 yHijri -= 0.001 } else if (intSisaHari === 1) { mHijri = intBulan1 + 1 yHijri += 0.001 } else { if ((intBulan1 + 1) % 12 === 0) { mHijri = 12 } else { mHijri = (intBulan1 + 1) % 12 } } yHijri = Math.trunc(yHijri) if (mHijri === 0) mHijri = 1 return formatReadDate(yHijri, mHijri, dHijri) }
function HijriToMasehi(year: number, month: number, day: number) { const intAW: number = 227016 const intAH: number = Math.trunc((11 * year) / 30) + Math.trunc(354 * year) + Math.trunc(30 * month) - Math.trunc((month - 1) / 2) + day - 384 const intAM: number = intAH + intAW const intTHM1: number = Math.trunc(intAM / 1461) * 4 const intDayCount: number = Math.ceil(intAM % 1461) const intAddYear: number = Math.trunc(intDayCount / 365) const intTHM2: number = intTHM1 + intAddYear + 1 const intA: number = intDayCount % 365 const intB: number = intAM < 577748 ? 0 : 2 - Math.trunc(intTHM2 / 100) + Math.trunc(Math.trunc(intTHM2 / 100) / 4) const intSisa: number = intA - intB const JH = [31, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 31] JH[2] = intTHM2 % 4 === 0 || intTHM2 % 100 === 0 || intTHM2 % 400 === 0 ? 29 : 28 const JLH = [0, 31] let intMatch: number = 0 for (let x = 1; x <= 12; x++) { JLH[x] = JLH[x - 1] + JH[x] } let intDaysYear: number = 0 for (let x = 1; x <= 12; x++) { intDaysYear += JH[x] } for (let x = 1; x <= 12; x++) { if (intSisa >= JLH[x - 1] && intSisa <= JLH[x]) { intMatch = x - 1 break } } const intBulan1: number = intSisa < 31 ? 0 : intMatch const intJmlHari: number = JLH[intBulan1] let intSisaHari: number = intSisa - intJmlHari let yMasehi: number = intTHM2 if (intSisaHari >= intDaysYear) { intSisaHari = intSisaHari - intDaysYear } let dMasehi: number = intSisaHari === 0 ? JH[intBulan1] : intSisaHari let mMasehi: number = 0 if (intSisaHari === 0) { yMasehi += 1 mMasehi = intBulan1 } else { if ((intBulan1 + 1) % 12 === 0) { mMasehi = 12 } else { mMasehi = (intBulan1 + 1) % 12 } } if (mMasehi === 0) mMasehi = 1 return formatReadDate(yMasehi, mMasehi, dMasehi) }
const formatReadDate = (year: number, month: number, day: number): string => { return [year, ('0' + month).slice(-2), ('0' + day).slice(-2)].join('-') }
Jika hasil perhitungan tidak akurat, tidak sesuai dengan perhitungan kalender Hijriyah di Indonesia atau yang ditampilkan pada menu Kalender di situs ini, tentunya sudah suatu keniscayaan seperti sudah dijelaskan sebelumnya, rumus ini hanya berdasarkan hisab Urfi.