amrosslee / global-prayer-times
Offline, framework-independent Islamic prayer-time calculations
Requires
- php: ^8.3
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.89
- phpstan/phpstan: ^2.1
- phpunit/phpunit: ^11.5
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
Framework-independent, offline Islamic prayer-time calculations for PHP. Stable release 1.0.0
is available on Packagist. Prayer-time conventions vary, and the configurable polar fallbacks are
explicit approximations rather than a guarantee for every locality or scholarly convention.
Requirements
- PHP 8.3 or newer
- Composer
Install
Install the latest stable release with Composer:
composer require amrosslee/global-prayer-times:^1.0
See the Packagist package page.
Supported features
This increment implements:
- Named presets: Muslim World League (18/17 degrees), ISNA (15/15), Egyptian (19.5/17.5), Umm al-Qura (18.5 degrees Fajr; Isha 90 minutes after sunset), Karachi (18/18), Jafari (16/14 degrees Fajr/Isha; 4 degrees Maghrib), and Tehran (17.7/14; 4.5 degrees Maghrib).
- Custom Fajr, Isha-angle or Isha-interval, and optional Maghrib-angle parameters.
- Standard and Hanafi Asr.
- Per-prayer minute adjustments.
- High-latitude Fajr/Isha rules: middle of the night, seventh of the night, or twilight-angle fraction.
- Polar sunrise/sunset policies: explicitly unresolved, nearest valid date, or nearest valid latitude.
- Explicit Gregorian local date, coordinates, and IANA timezone inputs.
- Immutable result values containing Fajr, sunrise, Dhuhr, Asr, Maghrib, and Isha.
Named presets include method defaults, such as a one-minute Dhuhr adjustment for MWL, ISNA, Egyptian, and Karachi. Caller-provided prayer adjustments are added to those defaults. Umm al-Qura uses a fixed 90-minute Isha interval; to follow the documented Ramadan convention, pass an additional Isha adjustment for the relevant dates.
Configuration template
The package includes config/global-prayer-times.php, a plain PHP
array of suggested defaults and supported options, formatted in the familiar Laravel configuration
style. It does not call Laravel's env() helper, load itself automatically, or set global state.
Applications should read their own configuration and pass an explicit CalculationSettings
instance to each calculation. Use the named CalculationSettings factories for built-in methods
and CalculationSettings::custom() for custom parameters.
Use the template in Laravel
This standalone package does not provide a Laravel service provider, so Laravel's
php artisan vendor:publish command cannot publish this file. After installing the package, copy
the template into your application's config directory:
cp vendor/amrosslee/global-prayer-times/config/global-prayer-times.php config/global-prayer-times.php
The copied file is now application-owned and can be edited like any other Laravel config file.
Laravel will make its values available through config('global-prayer-times.method'). The package
does not automatically convert that array into calculation settings; your application should map
the chosen values to a CalculationSettings factory and pass the resulting settings explicitly
when calculating prayer times. Since the file is copied rather than registered with Laravel,
package updates will not overwrite your application's copy.
When sunrise or sunset is absent for the requested date, the default Unresolved polar policy
throws CalculationException. NearestValidDate searches up to 183 days before and after the
requested date, preferring the next valid date at equal distances. NearestValidLatitude searches
toward the equator in 0.5-degree steps while keeping longitude fixed. Either policy borrows solar
event times from the resolved date or latitude; those borrowed UTC time-of-day values are applied
to the requested calendar date, so a returned local time can fall on the following or preceding
date after timezone conversion. These are explicit approximation policies, not a claim that a
location at the pole has ordinary daily sunrise and sunset.
The default MiddleOfTheNight high-latitude rule bounds Fajr and angle-based Isha by half the
calculated night. SeventhOfTheNight uses one seventh; TwilightAngle uses the configured twilight
angle divided by 60. A method using an Isha interval (such as Umm al-Qura) calculates Isha from
sunset and that interval instead.
use GlobalPrayerTimes\CalculationSettings; use GlobalPrayerTimes\HighLatitudeRule; use GlobalPrayerTimes\PolarResolution; $settings = CalculationSettings::isna( highLatitudeRule: HighLatitudeRule::SeventhOfTheNight, polarResolution: PolarResolution::NearestValidDate, );
use GlobalPrayerTimes\Calculation\PrayerTimesCalculator; use GlobalPrayerTimes\CalculationSettings; use GlobalPrayerTimes\Coordinates; use GlobalPrayerTimes\LocalDate; $times = (new PrayerTimesCalculator())->calculate( LocalDate::fromString('2026-10-18'), new Coordinates(40.7128, -74.0060), 'America/New_York', CalculationSettings::muslimWorldLeague(), ); echo $times->fajr->format('H:i');
Date is a local Gregorian calendar date in the supplied timezone. The calculator uses local noon to
anchor the astronomical UTC date, which preserves the requested date across the International Date
Line, then returns each DateTimeImmutable in the explicitly supplied timezone. The PHP process
timezone is not consulted.
Algorithm and attribution
The solar-position and event-time implementation is adapted from the Adhan JavaScript library's
Meeus-based calculation core. The inspected upstream project is
batoulapps/adhan-js, licensed MIT, at development commit
46ed34d
dated 2026-10-12. The port adapts calculations from SolarCoordinates.ts, Astronomical.ts, and
SolarTime.ts; the upstream MIT notice is retained in LICENSE. This PHP port uses no
runtime dependency and does not copy the JavaScript package into the published package.
The nearest-valid-date and nearest-valid-latitude polar resolution approaches also follow Adhan's
MIT-licensed PolarCircleResolution.ts,
with explicit finite search limits and exceptions when a valid substitute cannot be found.
Named method parameters are documented in Adhan's Calculation Parameters Guide. The Jafari parameter values (Fajr 16 degrees, Maghrib 4 degrees, Isha 14 degrees) are from PrayTimes v2.5, which identifies its source as LGPL-3.0. This package consults the method values only; it does not copy or adapt PrayTimes code.
Reference data provenance and tolerances are recorded in tests/fixtures/README.md. Prayer-time conventions and published timetables can differ; a few matching fixtures do not imply universal religious or astronomical accuracy.
Development
composer install
composer test
composer analyse
composer style
When actively developing the package alongside an application, you can optionally use this local checkout through a Composer path repository (adjust the relative path as needed). This is not required for normal installation; use the Packagist install command above otherwise.
{
"repositories": [
{
"type": "path",
"url": "../prayer-times-calcs",
"options": {
"symlink": true
}
}
],
"require": {
"amrosslee/global-prayer-times": "*"
}
}
Then run composer update amrosslee/global-prayer-times in the application.
Release and coverage status
Release 1.0.0 is published on Packagist. CI runs the test, static-analysis, and style checks on
PHP 8.3, 8.4, and 8.5. Reference comparisons cover selected methods and scenarios, not every
method/location/date combination; in particular, Karachi and Jafari currently have configuration
and calculation smoke coverage but no dedicated numerical reference fixtures. Results should be
validated against local scholarly or institutional guidance when exact timetable conformity is
required. See tests/fixtures/README.md for sources, tolerances, and
known limits.
For subsequent releases, update CHANGELOG.md, run the checks above, push a semantic-version tag,
and verify that the new version appears on Packagist and installs in a clean Composer project.