در این صفحه
معرفی#
کلاس RtlyKit\Prayer\PrayerTimes شش وقت روزانه را با معادلههای نجومی حساب میکند. اینترنت و فایل داده لازم نیست. میل خورشید و معادلهٔ زمان از سریهای سادهشدهٔ ژان میوس در کتاب Astronomical Algorithms گرفته شده (همان معادلههای ماشینحساب خورشیدی NOAA). زاویهٔ ساعتی با مثلثات کروی به دست میآید. عصر با ضریب طول سایه حساب میشود و طلوع و غروب با ارتفاع -0٫833 درجه (شکست نور بهعلاوهٔ نیمقطر خورشید). زاویههای صبح و مغرب و عشا همان قراردادهای منتشرشدهٔ هر روشاند.
نتیجه رشتههایی مثل HH:MM به وقت محلی منطقهٔ زمانی محاسبهگر است و به نزدیکترین دقیقه گرد میشود.
شروع سریع#
use RtlyKit\Prayer\PrayerTimes;
$tz = new DateTimeZone('Asia/Tehran');
$day = new DateTimeImmutable('2026-03-21 12:00', $tz);
$times = PrayerTimes::forCity('tehran')->getTimes($day);
echo json_encode($times);
// {"fajr":"04:43","sunrise":"06:07","dhuhr":"12:12","asr":"15:39","maghrib":"18:35","isha":"19:22"}
اگر تاریخ ندهید، getTimes() امروز را در منطقهٔ زمانی محاسبهگر برمیدارد. تاریخی که میدهید، روز تقویمی محلی همان منطقه را مشخص میکند. یک میانبر فضاینامدار هم هست که همین آرایه را برای امروز میدهد: \RtlyKit\prayer_times('tehran', 'Tehran') (توابع کمکی و سراسری).
ساختن محاسبهگر#
دو راه دارد.
// ۱) شهر داخلی: مختصات و منطقهٔ زمانی خودکار پر میشود.
$p = PrayerTimes::forCity('mecca', PrayerTimes::METHOD_MAKKAH);
// ۲) مختصات دلخواه.
$p = new PrayerTimes(
latitude: 35.6892,
longitude: 51.3890,
method: PrayerTimes::METHOD_TEHRAN, // پیشفرض
asrFactor: PrayerTimes::ASR_STANDARD, // پیشفرض
timezone: new DateTimeZone('Asia/Tehran'), // پیشفرض: date_default_timezone_get()
elevation: 0.0, // متر، پیشفرض ۰
);
forCity() این نامها را میشناسد (بزرگی و کوچکی حرف مهم نیست): tehran، mashhad، isfahan، shiraz، tabriz، qom، mecca، medina، riyadh، istanbul، cairo، dubai، baghdad، jakarta. نام دیگر خطا میدهد. برای شهرهای دیگر سازنده را با مختصات خودتان صدا بزنید.
روشها و زاویهها#
روش، زاویهٔ فرورفتن خورشید را برای صبح و عشا (و در تهران برای مغرب) مشخص میکند. بهجای رشته از ثابتهای کلاس استفاده کنید.
| ثابت | صبح | مغرب | عشا |
|---|---|---|---|
METHOD_TEHRAN (Tehran، پیشفرض) | ۱۷٫۷ درجه | خورشید ۴٫۵ درجه زیر افق | ۱۴ درجه |
METHOD_MWL (MWL) | ۱۸ درجه | غروب | ۱۷ درجه |
METHOD_ISNA (ISNA) | ۱۵ درجه | غروب | ۱۵ درجه |
METHOD_EGYPT (Egypt) | ۱۹٫۵ درجه | غروب | ۱۷٫۵ درجه |
METHOD_MAKKAH (Makkah) | ۱۸٫۵ درجه | غروب | مغرب + ۹۰ دقیقه (در رمضان + ۱۲۰ دقیقه) |
METHOD_KARACHI (Karachi) | ۱۸ درجه | غروب | ۱۸ درجه |
همین روز در تهران با هر شش روش. فقط صبح و مغرب و عشا فرق میکنند. طلوع و ظهر و عصر به روش بستگی ندارند:
foreach (['Tehran', 'MWL', 'ISNA', 'Egypt', 'Makkah', 'Karachi'] as $m) {
echo str_pad($m, 8), json_encode(PrayerTimes::forCity('tehran', $m)->getTimes($day)), "\n";
}
// Tehran {"fajr":"04:43","sunrise":"06:07","dhuhr":"12:12","asr":"15:39","maghrib":"18:35","isha":"19:22"}
// MWL {"fajr":"04:42","sunrise":"06:07","dhuhr":"12:12","asr":"15:39","maghrib":"18:17","isha":"19:37"}
// ISNA {"fajr":"04:57","sunrise":"06:07","dhuhr":"12:12","asr":"15:39","maghrib":"18:17","isha":"19:27"}
// Egypt {"fajr":"04:34","sunrise":"06:07","dhuhr":"12:12","asr":"15:39","maghrib":"18:17","isha":"19:40"}
// Makkah {"fajr":"04:39","sunrise":"06:07","dhuhr":"12:12","asr":"15:39","maghrib":"18:17","isha":"19:47"}
// Karachi {"fajr":"04:42","sunrise":"06:07","dhuhr":"12:12","asr":"15:39","maghrib":"18:17","isha":"19:42"}
ظهر همان لحظهٔ عبور خورشید از نصفالنهار است. به هیچ وقتی زمان احتیاط اضافه نمیشود.
مذهبهای عصر#
عصر وقتی شروع میشود که سایهٔ هر جسم برابر سایهٔ ظهر بهعلاوهٔ مضربی از ارتفاع جسم شود. ASR_STANDARD (مقدار ۱، یک برابر ارتفاع) برای شافعی، مالکی، حنبلی و جعفری است. ASR_HANAFI (مقدار ۲، دو برابر ارتفاع) وقت دیرتری میدهد.
$hanafi = PrayerTimes::forCity('tehran', 'Tehran', PrayerTimes::ASR_HANAFI);
echo $hanafi->getTimes($day)['asr']; // 16:32 (استاندارد: 15:39)
مکه: عشا در رمضان#
در قرارداد امالقری، عشا ۹۰ دقیقه بعد از مغرب است و در رمضان ۱۲۰ دقیقه بعد از مغرب. اگر روز تقویمی محلی در رمضانِ جدول امالقریِ همین کتابخانه باشد (ماه ۹)، ۱۲۰ دقیقه به کار میرود، وگرنه ۹۰. تشخیص بر اساس تاریخ مدنی است، نه روز اسلامی که از غروب شروع میشود.
$mk = PrayerTimes::forCity('mecca', 'Makkah');
foreach (['2026-02-20', '2026-03-01', '2026-03-21'] as $s) {
$t = $mk->getTimes(new DateTimeImmutable($s, new DateTimeZone('Asia/Riyadh')));
echo $s, ' maghrib ', $t['maghrib'], ' isha ', $t['isha'], "\n";
}
// 2026-02-20 maghrib 18:21 isha 20:21 (+120، رمضان)
// 2026-03-01 maghrib 18:25 isha 20:25 (+120، رمضان)
// 2026-03-21 maghrib 18:32 isha 20:02 (+90، بعد از رمضان)
ارتفاع از سطح دریا#
آرگومان elevation ارتفاع ناظر از سطح دریا بر حسب متر است. ارتفاع طلوع و غروب را به اندازهٔ فرورفتگی هندسی افق کم میکند، یعنی 0.0347 * sqrt(h) درجه. پس در ارتفاع، طلوع زودتر و غروب دیرتر میشود. مقدار منفی صفر حساب میشود. اثرش فقط روی طلوع و غروب و وقتهایی است که از غروب میآیند.
$a = new PrayerTimes(35.6892, 51.3890, 'Tehran', 1, $tz);
$b = new PrayerTimes(35.6892, 51.3890, 'Tehran', 1, $tz, 1500.0);
$d = new DateTimeImmutable('2026-06-21', $tz);
echo $a->getTimes($d)['sunrise'], "\n"; // 04:49
echo $b->getTimes($d)['sunrise'], "\n"; // 04:41
در روش تهران مغرب با زاویهٔ ۴٫۵ درجه تعریف میشود، نه با غروب. پس با ارتفاع عوض نمیشود (در هر دو حالت بالا 19:45).
منطقهٔ زمانی و ساعت تابستانی#
هر وقت با اختلاف واقعی UTC همان لحظه به وقت محلی تبدیل میشود. پس تغییر ساعت تابستانی بدون کار اضافه درست کار میکند. برلین در ۲۹ مارس ۲۰۲۶ ساعت را تغییر میدهد:
$tzb = new DateTimeZone('Europe/Berlin');
$ber = new PrayerTimes(52.52, 13.405, 'MWL', 1, $tzb);
foreach (['2026-03-28', '2026-03-29'] as $s) {
echo $s, ' ', json_encode($ber->getTimes(new DateTimeImmutable($s, $tzb))), "\n";
}
// 2026-03-28 {"fajr":"03:51","sunrise":"05:50","dhuhr":"12:11","asr":"15:39","maghrib":"18:34","isha":"20:26"}
// 2026-03-29 {"fajr":"04:48","sunrise":"06:48","dhuhr":"13:11","asr":"16:40","maghrib":"19:35","isha":"21:28"}
منطقهای بدهید که کاربرانتان ساعتشان را با آن میخوانند. اگر ندهید، date_default_timezone_get() به کار میرود.
نماز بعدی#
متد nextPrayer() اولین نمازی را میدهد که بعد از یک لحظه (پیشفرض: همین الان) باشد. بعد از عشا به اذان صبح فردا میرسد و کلید date میگوید نماز برگشتی مال کدام روز است. نمازی که بعد از نیمهشب بیفتد (مثلاً عشا یا صبح در عرضهای بالا) هم با تاریخ خودش پیدا میشود.
$p = PrayerTimes::forCity('tehran');
echo json_encode($p->nextPrayer(new DateTimeImmutable('2026-03-21 10:00', $tz)));
// {"name":"dhuhr","time":"12:12","date":"2026-03-21"}
echo json_encode($p->nextPrayer(new DateTimeImmutable('2026-03-21 20:00', $tz)));
// {"name":"fajr","time":"04:42","date":"2026-03-22"}
طلوع هم در این ترتیب یک مورد است (ترتیب: fajr، sunrise، dhuhr، asr، maghrib، isha). اگر وقتی را با withTune() جابهجا کرده باشید، nextPrayer() با وقتهای جابهجاشده کار میکند.
عرضهای جغرافیایی بالا#
در عرضهای بالا، تابستانها خورشید گاهی به زاویهٔ صبح یا عشا نمیرسد (شب واقعی نیست). برای این حالت HighLatitudeRule هست. چهار قاعده دارد:
| قاعده | صبح و عشا را در چه حدی نگه میدارد |
|---|---|
HighLatitudeRule::AngleBased (پیشفرض) | زاویه تقسیم بر ۶۰ از طول شب (برای ۱۸ درجه، ۰٫۳ شب) |
HighLatitudeRule::NightMiddle | نیمی از شب |
HighLatitudeRule::OneSeventh | یکهفتم شب |
HighLatitudeRule::None | بدون تغییر. وقتی زاویه به دست نیاید، مقدار null است |
«شب» یعنی از غروب تا طلوع روز بعد. قاعده فقط وقتی کار میکند که وقتی تعریفنشده (null) باشد یا از حد شبِ قاعده دورتر بیفتد. وقتهای دیگر مقدار نجومی خودشان را نگه میدارند. عشای ثابت مکه (مغرب + دقیقه) زاویه نیست و قاعده آن را عوض نمیکند.
use RtlyKit\Prayer\HighLatitudeRule;
$sto = new PrayerTimes(59.33, 18.07, 'MWL', 1, new DateTimeZone('Europe/Stockholm'));
$d = new DateTimeImmutable('2026-06-21', new DateTimeZone('Europe/Stockholm'));
echo json_encode($sto->getTimes($d)), "\n";
// {"fajr":"01:54","sunrise":"03:31","dhuhr":"12:50","asr":"17:30","maghrib":"22:08","isha":"23:40"}
echo json_encode($sto->withHighLatitudeRule(HighLatitudeRule::OneSeventh)->getTimes($d)), "\n";
// {"fajr":"02:45","sunrise":"03:31","dhuhr":"12:50","asr":"17:30","maghrib":"22:08","isha":"22:54"}
echo json_encode($sto->withHighLatitudeRule(HighLatitudeRule::None)->getTimes($d)), "\n";
// {"fajr":null,"sunrise":"03:31","dhuhr":"12:50","asr":"17:30","maghrib":"22:08","isha":null}
در روز و شب قطبی، طلوع و غروب null میشوند (خورشید واقعاً طلوع یا غروب نمیکند). ظهر همیشه مقدار دارد. صبح و عشا با شبی مرجع حساب میشوند که طلوع را ساعت ۶ و غروب را ساعت ۱۸ خورشیدی فرض میکند. این قرارداد خود کتابخانه است، نه قرارداد منتشرشده. اگر چیز دیگری میخواهید، None را بزنید و خودتان تصمیم بگیرید.
AngleBased) فقط جایی اثر میکند که وقتی تعریفنشده باشد یا از حد شبش دورتر بیفتد. شمال حدود ۴۴ تا ۴۶ درجه، نزدیک انقلاب تابستانی (ژوئن)، بعضی وقتهای صبح و عشا با نسخههای ۰٫۱ فرق دارند. در جنوب ۴۴ درجه خروجی همان است. اگر خروجی قبلی را میخواهید، withHighLatitudeRule(HighLatitudeRule::None) را بزنید.تنظیم دستی دقیقهها#
بعضی مراجع محلی چند دقیقه احتیاط اضافه میکنند. با withTune() میتوانید برای هر وقت یک عدد صحیح از -۳۰ تا ۳۰ دقیقه بدهید. کلیدها fajr، sunrise، dhuhr، asr، maghrib و isha هستند. وقتی که نام نبرید صفر است. هر بار صدا زدن، تنظیم قبلی را عوض میکند و withTune([]) آن را پاک میکند. دقیقهها به وقت اضافه میشوند، پس وقت میتواند از نیمهشب هم رد شود.
$p = PrayerTimes::forCity('tehran');
echo json_encode($p->withTune(['fajr' => 2, 'maghrib' => 3])->getTimes($day)), "\n";
// {"fajr":"04:45","sunrise":"06:07","dhuhr":"12:12","asr":"15:39","maghrib":"18:38","isha":"19:22"}
echo json_encode($p->getTimes($day)), "\n"; // خود $p تغییر نکرده
// {"fajr":"04:43","sunrise":"06:07","dhuhr":"12:12","asr":"15:39","maghrib":"18:35","isha":"19:22"}
هر دو متد withHighLatitudeRule() و withTune() یک نمونهٔ تازه برمیگردانند و نمونهٔ اصلی عوض نمیشود.
خطاها#
تنظیم نامعتبر InvalidPrayerConfigException میدهد. این کلاس از RtlyKitException (و از آنجا \InvalidArgumentException) ارث میبرد. مثلاً:
new PrayerTimes(35, 51, 'Foo');
// Unknown calculation method: Foo. Available: MWL, ISNA, Egypt, Makkah, Karachi, Tehran
new PrayerTimes(35, 51, 'MWL', 3);
// Invalid Asr factor: 3 (use 1 or 2)
PrayerTimes::forCity('paris');
// Unknown city: paris
$p->withTune(['fajr' => 40]);
// Tune for fajr must be an integer from -30 to 30 minutes
$p->withTune(['foo' => 1]);
// Unknown tune key: foo. Available: fajr, sunrise, dhuhr, asr, maghrib, isha
برای اینکه همهٔ خطاهای کتابخانه را با یک catch بگیرید، مدیریت خطا را ببینید.
چه چیزهایی را بررسی کردهایم#
زاویهها قرارداد هستند. پس بررسی درست این است که خروجی ما را برای یک شهر و تاریخ با جدول منتشرشدهٔ همان مرجع مقایسه کنیم. تا ۱ دقیقه اختلاف را همخوانی حساب کردهایم. سایتهای تجمیعکننده را نشمردهایم، چون آنها هم از همان زاویهها استفاده میکنند و مقایسه با آنها چیزی را ثابت نمیکند.
| روش | چه چیزی را سنجیدهایم | بیشترین اختلاف | مرجع |
|---|---|---|---|
| تهران | صبح، طلوع، ظهر و مغرب | ۱ دقیقه (شیراز)، در بقیه ۰ | جدولهای ۱۴۰۵ مؤسسهٔ ژئوفیزیک دانشگاه تهران: تهران، مشهد، اصفهان و شیراز در چهار تاریخ. |
| مکه | همهٔ وقتها، از جمله عشای رمضان | ۱ دقیقه | تقویم امالقری (KACST): پنج تاریخ بیرون از رمضان و دو تاریخ در رمضان ۱۴۴۷. |
| مصر | هر شش وقت | ۱ دقیقه | جدول دارالافتاء، قاهره، چند تاریخ در اکتبر 2026. |
| ترکیه (دیانت) | صبح و عشا. با زاویههای ۱۸ و ۱۷ درجه (مثل MWL) هماهنگ است | ۱ دقیقه | جدولهای ریاست امور دینی برای استانبول، آنکارا و ازمیر، از ۸ اکتبر تا ۷ نوامبر 2026. |
| کراچی با عصر حنفی | همهٔ وقتها. همخوان با یک جدول منتشرشدهٔ کراچی | ۱ دقیقه | جدول اکتبر 2026 جامعه علوم اسلامیه بنوریتاون، کراچی: ۳۱ روز. |
| عصر حنفی (ضریب ۲) | تعریف | - | تعریف مدرسهٔ دارالعلوم دیوبند. |
| ISNA (۱۵ و ۱۵) | زاویهها | - | جفت زاویهای که شورای فقهی آمریکای شمالی برای این روش میگوید. |
| طلوع و غروب | همهٔ شهرها | ۱ دقیقه | ۱۱ جفت شهر و تاریخ در برابر timeanddate و ماشینحساب NOAA. |