
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.