DEV Community

Chiem The
Chiem The

Posted on

Your prayer-times app is probably 2 minutes early in Indonesia

I maintain a small offline prayer-times app (Flutter, no backend). It computes times on the phone with the adhan library. This week I added Indonesian and Malay, and a test against official timetables turned up something worth sharing.

The setup

Indonesia's Ministry of Religious Affairs (Kemenag) publishes the official schedule. Its angles are well documented: Fajr (Subuh) at 20 degrees below the horizon, Isha at 18. adhan ships a method with exactly those angles (it is called Singapore), so I expected an exact match.

It was not. Against Kemenag's Jakarta table for 1 Ramadan 1447 (19 Feb 2026) and 30 Ramadan (20 Mar 2026):

Prayer Raw 20/18 Kemenag Diff
Subuh 04:40 04:41 / 04:42 +1 to +2
Dhuhr 12:02 12:04 +2
Asr 15:11 15:13 +2
Maghrib 18:15 / 18:04 18:18 / 18:07 +3
Isya 19:13 19:15 +2

Why

Kemenag adds an ihtiyat, a precautionary margin of about two minutes, to each time. The angles alone do not reproduce it. Maghrib came out three minutes later in both samples.

That matters more than it looks: Maghrib is iftar. An app that is two minutes early tells people to break their fast before the official time, during the one month they check it most.

The fix

The engine already supported per-prayer minute offsets (for matching a local mosque), so the fix was a regional default instead of new math:

static const kemenagIhtiyat = <PrayerName, int>{
  PrayerName.fajr: 1,    // Imsak (Subuh - 10) never later than official
  PrayerName.sunrise: -2,
  PrayerName.dhuhr: 2,
  PrayerName.asr: 2,
  PrayerName.maghrib: 3, // iftar never earlier than official
  PrayerName.isha: 2,
};
Enter fullscreen mode Exit fullscreen mode

The rounding is deliberate and asymmetric. Where the measured offset ranged, I picked the side that errs safely: Maghrib +3 so iftar is never early, Subuh +1 so the Imsak cutoff is never late.

A test pins one real day so the defaults cannot drift:

expect(hm(day.imsak()).compareTo('04:31') <= 0, isTrue);
expect(hm(day.maghrib).compareTo('18:18') >= 0, isTrue);
Enter fullscreen mode Exit fullscreen mode

Malaysia was a different story: the official Kuala Lumpur Imsak matched raw Subuh at 20 degrees, which means the official Subuh runs 9 to 10 minutes later, closer to 18 degrees. Same mechanism, different numbers.

Takeaway

If you build anything that computes religious or legal times, test against the published table of the authority people actually follow, not against the method name in the library. Two data points per region caught both issues.

The app is Namaz Time on Google Play, if you want to see it: https://play.google.com/store/apps/details?id=com.pipex.namaztime&referrer=utm_source%3Ddevto%26utm_medium%3Dsocial%26utm_campaign%3Darticle

Top comments (0)