PrayerTimePlus

main

Offline Islamic prayer times & Sunnah times for Swift (iOS/macOS/watchOS/tvOS/Linux) — 50+ calculation methods, country Auto-resolution, zero dependencies. Also on Dart & Kotlin.
abdulwahed-s/prayer-time-plus-swift

PrayerTimePlus

Swift Package Index Platforms License: MIT

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.

Requirements

  • Swift 6.3+
  • macOS 10.15+, iOS 13+, tvOS 13+, watchOS 6+ (and Linux, Foundation only)

Installation

Add the package to your Package.swift:

dependencies: [
    .package(url: "https://github.com/abdulwahed-s/prayer-time-plus-swift.git", from: "0.1.0"),
]

Then add the product to your target:

.target(
    name: "YourTarget",
    dependencies: [
        .product(name: "PrayerTimePlus", package: "prayer-time-plus-swift"),
    ]
)

Quick start

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:35

Each 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.

Initialization

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.

Calculation methods

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.

Madhab

Madhab Asr shadow factor
.shafi 1 (Shāfiʿī / Mālikī / Ḥanbalī)
.hanafi 2 (Ḥanafī)
var params = CalculationMethod.karachi.parameters
params.madhab = .hanafi

High-latitude rule

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.

Auto resolution

Resolve a method from a country code:

AutoMethod.forCountry("OM")   // .oman
AutoMethod.forCountry("SA")   // .ummAlQura
AutoMethod.forCountry("fr")   // .uoif  (case-insensitive)

Sunnah times

let sunnah = SunnahTimes(from: times)
sunnah.middleOfTheNight      // Date?
sunnah.lastThirdOfTheNight   // Date?

Custom offsets

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)

The current and next prayer are available directly:

times.currentPrayer()   // Prayer?
times.nextPrayer()      // Prayer?

Dates and time zones

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.

Command-line demo

swift run prayer-time-plus-cli

Documentation

Every 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.

Other platforms

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.

License

MIT — see LICENSE.

Description

  • Swift Tools 6.3.0
View More Packages from this Author

Dependencies

  • None
Last updated: Sun Jul 12 2026 07:47:36 GMT-0900 (Hawaii-Aleutian Daylight Time)