A native, dependency-free Swift package for computing Islamic prayer times. It pairs Adhan-style ergonomics with a specific reference engine's angles, per-prayer offsets and country-based "Auto" resolution — matching that engine to the minute.
Also available for Dart / Flutter and Kotlin / JVM. All three are faithful ports of the same solar engine and compute identical times to the minute. See Other platforms.
- Zero third-party dependencies — Swift standard library and Foundation only.
- Deterministic — the timezone enters as a caller-supplied offset; there is no timezone database and no network.
- Customizable — every angle, interval, offset, madhab and high-latitude rule is overridable.
- Swift 6.3+
- macOS 10.15+, iOS 13+, tvOS 13+, watchOS 6+ (and Linux, Foundation only)
Add the package to your Package.swift:
dependencies: [
.package(url: "https://github.com/abdulwahed-s/prayer-time-plus-swift.git", from: "0.3.0"),
]Then add the product to your target:
.target(
name: "YourTarget",
dependencies: [
.product(name: "PrayerTimePlus", package: "prayer-time-plus-swift"),
]
)import PrayerTimePlus
let times = PrayerTimes(
coordinates: Coordinates(latitude: 24.3486, longitude: 56.6953, altitude: 5),
date: DateComponents(year: 2026, month: 6, day: 28),
calculationParameters: CalculationMethod.oman.parameters,
utcOffset: 4 * 3600, // seconds east of UTC (include DST yourself)
countryCode: "OM",
cityName: "sohar"
)
let formatter = DateFormatter()
formatter.dateFormat = "HH:mm"
formatter.timeZone = TimeZone(secondsFromGMT: 4 * 3600)
for prayer in Prayer.allCases {
let value = times.time(for: prayer).map { formatter.string(from: $0) } ?? "--:--"
print("\(prayer): \(value)")
}
// fajr: 03:59, sunrise: 05:27, dhuhr: 12:21, asr: 15:42, maghrib: 19:10, isha: 20:35Each returned value is a true UTC Date (or nil when the sun never reaches the
required angle). Format it with a DateFormatter whose timeZone you set — the
instant itself carries no wall-clock zone.
| Parameter | Type | Description |
|---|---|---|
coordinates |
Coordinates |
Latitude, longitude (east-positive) and altitude. |
date |
DateComponents |
Only year, month and day are used. |
calculationParameters |
CalculationParameters |
Angles, offsets, madhab, high-latitude rule. |
utcOffset |
TimeInterval |
Seconds east of UTC, including any DST. |
countryCode |
String |
ISO-3166 alpha-2, for the elevation and Ramadan rules. |
cityName |
String |
Retained for reference. |
Use PrayerTimes.today(...) to compute for the current calendar day at a given
offset.
Obtain a preset from CalculationMethod and read .parameters:
let params = CalculationMethod.muslimWorldLeague.parameters| Method | Fajr | Isha |
|---|---|---|
.muslimWorldLeague |
18° | 17° |
.egyptian |
19.5° | 17.5° |
.karachi |
18° | 18° |
.ummAlQura |
18.5° | Maghrib + 90 min (120 in Ramadan) |
.northAmerica |
15° | 15° |
.emirates, .qatar, .kuwait, .oman, .turkey, … |
regional | regional |
See Documentation/CalculationMethods.md
for the full table, or enumerate CalculationMethod.allCases. Build a fully
custom method with .other, whose stable key is custom.
| Madhab | Asr shadow factor |
|---|---|
.shafi |
1 (Shāfiʿī / Mālikī / Ḥanbalī) |
.hanafi |
2 (Ḥanafī) |
var params = CalculationMethod.karachi.parameters
params.madhab = .hanafi| Rule | Behaviour |
|---|---|
.automatic |
Natural times, retried once with one-seventh if Fajr/Isha degenerate. Default. |
.unadjusted |
No fallback; Fajr/Isha may be nil near the poles. |
.middleOfTheNight |
Pins Fajr/Isha to the middle of the night. |
.seventhOfTheNight |
Pins Fajr/Isha within one-seventh of the night. |
.twilightAngle |
Pins Fajr/Isha to a fraction of the night from their angle. |
Resolve a method from a country code:
AutoMethod.forCountry("OM") // .oman
AutoMethod.forCountry("SA") // .ummAlQura
AutoMethod.forCountry("fr") // .uoif (case-insensitive)let sunnah = SunnahTimes(from: times)
sunnah.middleOfTheNight // Date?
sunnah.lastThirdOfTheNight // Date?var params = CalculationMethod.oman.parameters
params.madhab = .hanafi
params.highLatitudeRule = .seventhOfTheNight
params.adjustments.fajr = 2 // add 2 minutes to Fajr
params.isRamadan = true // Umm al-Qura +30 Isha (in SA)To configure custom Fajr, Maghrib, and Isha angles:
var params = CalculationMethod.other.parameters
params.fajrAngle = 18
params.maghribIsInterval = false
params.maghribValue = 4 // evening depression angle
params.ishaIsInterval = false
params.ishaValue = 17With maghribIsInterval == false, a positive maghribValue is the evening
solar-depression angle; zero or a negative value keeps Maghrib at Sunset. An
unavailable or non-chronological angle safely falls back to Sunset. With the
flag set to true, the value remains minutes after Sunset. Interval Isha is
always measured from the final Maghrib, including an angle-based one. The
Custom defaults are Fajr 18°, Maghrib at Sunset, and Isha 17°.
The current and next prayer are available directly:
times.currentPrayer() // Prayer?
times.nextPrayer() // Prayer?Julian day is computed from the calendar date only. The caller supplies
utcOffset in seconds (fold in DST yourself); the package has no timezone
database. Each returned Date is the true UTC instant — display it with a
DateFormatter whose timeZone you choose.
swift run prayer-time-plus-cliEvery public symbol carries a DocC comment. Build the documentation in Xcode with Product ▸ Build Documentation, or add swift-docc-plugin to generate it from the command line.
The same solar engine, ported idiomatically to three ecosystems — identical results to the minute:
| Platform | Package | Repository |
|---|---|---|
| Swift · iOS, macOS, watchOS, tvOS, Linux — you are here | Swift Package Index | prayer-time-plus-swift |
| Dart / Flutter | prayer_time_plus |
prayer_time_plus |
| Kotlin / JVM | io.github.abdulwahed-s:prayer-time-plus |
prayer-time-plus-kotlin |
The Swift-version and platform badges above are served by the Swift Package Index and stay current automatically once the package is indexed.
MIT — see LICENSE.