Accurate calculation of Islamic prayer times is a fascinating intersection of astronomy, mathematics, and software engineering. While building automated reminder bots and web services for Indonesian regions, I created JadwalSholat to provide reliable, zero-dependency prayer time schedules.
The Mathematical Foundation
Prayer times depend entirely on the Sun’s position relative to an observer’s geographic coordinates (latitude $\phi$, longitude $\lambda$) on Earth at a given date.
Sun Declination & Equation of Time
The Sun’s position shifts throughout the year due to Earth’s axial tilt (~23.44°) and elliptical orbit. Two fundamental variables must be computed for each day:
- Solar Declination ($\delta$): The angle between the rays of the Sun and the plane of the Earth’s equator.
- Equation of Time ($EoT$): The discrepancy between solar noon (sundial time) and mean solar noon (clock time).
From these values, Solar Noon (Dzuhur) is calculated as:
Dhuhr = 12 + Timezone - (Longitude / 15) - EoT Regional Nuances in Indonesia (Kemenag Standards)
Different Islamic organizations around the world use slightly different sun depression angles for twilight calculations:
- Subuh (Dawn): The Indonesian Ministry of Religious Affairs (Kementerian Agama RI) specifies a sun depression angle of 20.0° below the horizon.
- Isya (Night): Standardized at 18.0° below the horizon.
- Ihtiyat (Safety Buffer): Kemenag guidelines recommend adding an ihtiyat (precautionary margin) of +2 minutes to prayer schedules to ensure callers do not announce the adhan prematurely.
function calculateFajr(latitude, declination, dhuhr, angle = 20.0) {
const rad = (deg) => (deg * Math.PI) / 180;
const deg = (rad) => (rad * 180) / Math.PI;
const cosHourAngle =
(-Math.sin(rad(angle)) - Math.sin(rad(latitude)) * Math.sin(rad(declination))) /
(Math.cos(rad(latitude)) * Math.cos(rad(declination)));
const hourAngle = deg(Math.acos(cosHourAngle)) / 15;
return dhuhr - hourAngle + (2 / 60); // includes 2 min ihtiyat
} Designing the API for Bot Integrations
Discord bots and webhook clients need lightweight, deterministic JSON responses without bloated HTML scraping:
{
"status": "success",
"data": {
"city": "Pekanbaru",
"province": "Riau",
"timezone": "UTC+7",
"date": "2026-08-04",
"schedule": {
"imsak": "04:47",
"subuh": "04:57",
"terbit": "06:12",
"dhuha": "06:36",
"dzuhur": "12:21",
"ashar": "15:43",
"maghrib": "18:24",
"isya": "19:35"
}
}
} Building your own calculation engine avoids depending on external third-party scraping, eliminates latency, and ensures high availability for mission-critical notifications.