Engineering JadwalSholat: Precision Astronomical Prayer Timing API

• 2 min read • by Kurniawan Satria

Astronomical sun-angle calculations, Indonesian Ministry of Religious Affairs standards, and resilient REST API design.

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:

  1. Solar Declination ($\delta$): The angle between the rays of the Sun and the plane of the Earth’s equator.
  2. 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.