در این صفحه
این کلاس چه میکند#
کلاس RtlyKit\Calendar\Hebrew یک تاریخ و زمان در تقویم عبری (یهودی) است و تغییر نمیکند. با PHP خالص نوشته شده و به ext-calendar نیاز ندارد. تقویم حسابی ثابت را پیاده میکند: مولاد تیشری، چهار تعویق به نام دهییوت، و سالهایی با ۳۵۳، ۳۵۴ یا ۳۵۵ روز (عادی) و ۳۸۳، ۳۸۴ یا ۳۸۵ روز (کبیسه). مثل دو تقویم دیگر، یک DateTimeImmutable زیرش است و قرارداد CalendarDate را دارد (تبدیل و مقایسهٔ تاریخها).
<?php
require 'vendor/autoload.php';
use RtlyKit\Calendar\Hebrew;
use RtlyKit\Exceptions\InvalidDateException;
use function RtlyKit\hebrew_date; // تابع کمکی فضاینامدار، همان Hebrew::make()
$utc = new DateTimeZone('UTC');
شمارهٔ ماهها#
ماهها بر اساس جایگاهشان در سال، از تیشری (آغاز سال مدنی) شماره میخورند. در سال کبیسه آدار اول و آدار دوم دو ماه جدا هستند:
- ماههای ۱ تا ۵ همیشه تیشری، حشوان، کسلو، طوت و شواطاند.
- سال عادی: ۶ = آدار، ۷ = نیسان، ۸ = ایار، ۹ = سیوان، ۱۰ = تموز، ۱۱ = آو، ۱۲ = الول.
- سال کبیسه: ۶ = آدار اول، ۷ = آدار دوم، ۸ = نیسان، ۹ = ایار، ۱۰ = سیوان، ۱۱ = تموز، ۱۲ = آو، ۱۳ = الول.
ext-calendar خود PHP فرق دارد. الول در سال عادی ماه ۱۲ و در سال کبیسه ماه ۱۳ است. نیسان هم ماه ۷ یا ۸ است. شمارهٔ ماه را از خود Hebrew بگیرید (getMonth()، monthName()، monthsInYear()) و از جدول کتابخانهٔ دیگر کپی نکنید.foreach ([5784, 5785] as $y) {
$a = [];
for ($m = 1; $m <= Hebrew::monthsInYear($y); $m++) {
$a[] = $m.':'.Hebrew::monthName($y, $m).'('.Hebrew::daysInMonth($y, $m).')';
}
echo $y, ' ', implode(' ', $a), "\n";
}
// 5784 1:Tishrei(30) 2:Cheshvan(29) 3:Kislev(29) 4:Tevet(29) 5:Shevat(30) 6:Adar I(30) 7:Adar II(29) 8:Nisan(30) 9:Iyar(29) 10:Sivan(30) 11:Tammuz(29) 12:Av(30) 13:Elul(29)
// 5785 1:Tishrei(30) 2:Cheshvan(30) 3:Kislev(30) 4:Tevet(29) 5:Shevat(30) 6:Adar(29) 7:Nisan(30) 8:Iyar(29) 9:Sivan(30) 10:Tammuz(29) 11:Av(30) 12:Elul(29)
Hebrew::monthName($year, $month, $locale = 'en') زبانهای en، he و fa را دارد (زبان ناشناخته مثل en رفتار میکند). در سال عادی، ماه ۶ فقط «آدار» است.
ساخت تاریخ#
متد Hebrew::create($year, $month, $day, $hour = 0, $minute = 0, $second = 0, $timezone = null) طول واقعی ماه را در همان سال چک میکند (حشوان و کسلو بین ۲۹ و ۳۰ روز تغییر میکنند).
$e = Hebrew::create(5785, 1, 1, 0, 0, 0, $utc);
echo $e; // 5785/01/01 00:00:00
echo $e->toGregorian()->format('Y-m-d'); // 2024-10-03
echo Hebrew::create(5785, 7, 15, 0, 0, 0, $utc)->toGregorian()->format('Y-m-d'); // 2025-04-13 (۱۵ نیسان 5785)
echo Hebrew::create(5786, 1, 10, 0, 0, 0, $utc)->toGregorian()->format('Y-m-d l'); // 2025-10-02 Thursday
متد Hebrew::make($time = null, $timezone = null) این ورودیها را قبول میکند: DateTimeInterface، هر CalendarDate، زمان یونیکس، رشته یا null. تابع کمکیاش hebrew_date() است. اگر خود یک شیء Hebrew بدهید، همان بدون تغییر برمیگردد.
echo Hebrew::make('2025-10-07', $utc); // 5786/01/15 00:00:00
echo hebrew_date('2025-10-07')->format('Y/m/d F'); // 5786/01/15 Tishrei
echo Hebrew::make('5785/01/10', $utc); // 5785/01/10 00:00:00
echo Hebrew::make('0001-09-06')->format('Y/m/d'); // 3762/01/01
رشته چطور خوانده میشود#
- رقمهای فارسی و عربی به انگلیسی تبدیل میشوند و فاصلههای دو سر رشته حذف میشود. رشتهٔ خالی
InvalidDateExceptionمیدهد. - رشتهای با شکل
Y/m/dیاY-m-d(باH:i[:s]اختیاری) که سالش ۳۰۰۰ یا بیشتر باشد، تاریخ عبری است و ماه همان شمارهٔ ترتیبی بالاست. (این آستانه عکس جلالی و هجری است. آنها سال کمتر از ۱۷۰۰ را مال خودشان میدانند.) - هر رشتهٔ دیگر میلادی یا متن آزاد خوانده میشود.
پس '5785/01/10' عبری است و '2025-10-07' میلادی. رشتهٔ '3000/01/01' سال عبری ۳۰۰۰ حساب میشود، که از کمترین سالِ پشتیبانیشده کوچکتر است و خطای Invalid Hebrew date: 3000/1/1 میدهد.
بازهٔ سال و خطاها#
سال عبری از Hebrew::MIN_YEAR = 3762 تا Hebrew::MAX_YEAR = 13759 پشتیبانی میشود. این همان بخشی است که در سالهای میلادی ۱ تا ۹۹۹۹ میافتد. اولین روز، اول تیشری ۳۷۶۲ (برابر 0001-09-06) و آخرین روز، آخر الول ۱۳۷۵۹ (برابر 9999-11-03) است. هر چیز بیرون از آن InvalidDateException میدهد. متد isValid() بهجای خطا false میدهد.
foreach ([[3761, 1, 1], [13760, 1, 1], [5785, 13, 1], [5785, 3, 31]] as [$y, $m, $d]) {
try { Hebrew::create($y, $m, $d); }
catch (InvalidDateException $x) { echo $x->getMessage(), "\n"; }
}
// Invalid Hebrew date: 3761/1/1
// Invalid Hebrew date: 13760/1/1
// Invalid Hebrew date: 5785/13/1 (5785 سال عادی است: ۱۲ ماه)
// Invalid Hebrew date: 5785/3/31
echo Hebrew::create(5784, 13, 1) instanceof Hebrew ? 'ok' : ''; // ok (5784 سال کبیسه است)
try { Hebrew::make('0001-01-01'); }
catch (InvalidDateException $x) { echo $x->getMessage(); }
// Date out of the supported Hebrew range (3762..13759): 3761
متدهای محاسبهای daysInYear()، daysInMonth() و monthName() سالهای ۱ تا ۱۳۷۵۹ را قبول میکنند (سال ۰ خطای Hebrew year out of the supported range: 0 میدهد). فقط ساخت تاریخ از ۳۷۶۲ شروع میشود.
خواندن مقدارها#
گیرندهها همان قرارداد مشترکاند (getYear()، getMonth()، getDay()، اجزای زمان، getTimestamp()، getTimezone()، toGregorian()، toDateString()، toDateTimeString()). getMonth() همان شمارهٔ ترتیبی ماه را میدهد.
شمارهٔ روز هفته#
getDayOfWeek() و توکن w از یکشنبه شروع میکنند: ۰ = یکشنبه تا ۶ = شنبه (مثل هجری و PHP، برعکس جلالی). توکن N شمارهٔ ISO است (دوشنبه = ۱).
echo $e->getDayOfWeek(); // 4 (اول تیشری 5785 پنجشنبه بود)
foreach (range(0, 6) as $i) { echo $e->addDays($i)->getDayOfWeek(); } // 4560123
قالببندی#
format($pattern = 'Y/m/d H:i:s', $locale = 'en') با زبان en، he یا fa. رقمها همیشه لاتیناند. بکاسلش نویسهٔ بعدی را همانطور که هست مینویسد (بکاسلشِ آخر الگو نادیده گرفته میشود). الگوی بلندتر از Hebrew::MAX_FORMAT_LENGTH (۲۵۶ بایت) InvalidDateException با کد input_too_long میدهد.
echo $e->format('l j F Y'); // Thursday 1 Tishrei 5785
echo $e->format('l j F Y', 'he'); // חמישי 1 תשרי 5785
echo $e->format('l j F Y', 'fa'); // پنجشنبه 1 تشری 5785
echo Hebrew::create(5784, 6, 15, 0, 0, 0, $utc)->format('j F'); // 15 Adar I
echo Hebrew::create(5784, 7, 15, 0, 0, 0, $utc)->format('j F'); // 15 Adar II
| توکن | معنی |
|---|---|
Y y m n d j | سال، ماه (ترتیبی) و روز |
H G h g i s | زمان روز (۲۴ ساعته و ۱۲ ساعته) |
F M | نام ماه به زبان انتخابشده (آدار اول و دوم، یا فقط آدار، بسته به سال) |
l | نام روز هفته به زبان انتخابشده |
w N | یکشنبه = ۰. و شمارهٔ ISO با دوشنبه = ۱ |
z t L | شمارهٔ روز در سال از صفر. تعداد روزهای ماه. و ۱ برای سال کبیسه (۱۳ ماه) |
a A | am/pm و AM/PM |
S W c r | خالی. هفتهٔ ISO لحظهٔ میلادی. Y-m-d\TH:i:sP با تاریخ عبری. و RFC 2822 |
U e T P p O Z I u v | از لحظهٔ زیرین گرفته میشوند |
جابهجایی و برش#
متدها مثل جلالی هستند. دو قاعدهٔ مخصوص عبری را بدانید:
- ماهها ترتیبی شمرده میشوند و آدار اول و دوم دو ماه جدا هستند. اگر ماه مقصد کوتاهتر باشد، روز کم میشود. حجم محاسبه کم است (چرخههای کامل ۱۹ ساله و حداکثر ۱۹ گام سالانه) و به بزرگی
$monthsبستگی ندارد. - سالها «همان ماه» را نگه میدارند. اگر از سال کبیسه به سال عادی بروید، آدار اول و دوم هر دو به آدار میروند. از سال عادی به کبیسه، آدار به آدار دوم میرود.
$adar1 = Hebrew::create(5784, 6, 15, 0, 0, 0, $utc);
echo $adar1->addMonths(1)->format('Y/m/d F'); // 5784/07/15 Adar II
echo Hebrew::create(5784, 7, 15, 0, 0, 0, $utc)->addYears(1)->format('Y/m/d F'); // 5785/06/15 Adar
echo Hebrew::create(5785, 2, 29, 0, 0, 0, $utc)->addMonths(1); // 5785/03/29 00:00:00
echo Hebrew::create(5785, 5, 30, 0, 0, 0, $utc)->addMonths(1)->format('Y/m/d F'); // 5785/06/29 Adar (روز کم شد)
echo $e->endOfMonth(); // 5785/01/30 23:59:59
echo $e->endOfYear(); // 5785/12/29 23:59:59
مقایسه و اختلاف#
مقایسه روی لحظهها انجام میشود و هر تقویمی را قبول میکند. diffInMonths() ماه کامل عبری میشمارد (آدار اول و دوم جدا حساب میشوند). diffInYears() بر اساس سالگرد است. سال عبری ۱۲ یا ۱۳ ماه دارد، پس نمیشود ماهها را بر ۱۲ تقسیم کرد.
echo Hebrew::create(5784, 1, 1, 0, 0, 0, $utc)->diffInMonths(Hebrew::create(5785, 1, 1, 0, 0, 0, $utc)); // 13
echo Hebrew::create(5780, 3, 3, 0, 0, 0, $utc)->diffInYears(Hebrew::create(5785, 3, 2, 0, 0, 0, $utc)); // 4
محاسبههای تقویمی#
| متد | خروجی |
|---|---|
Hebrew::isValid($y, $m, $d) | bool |
Hebrew::isLeapYear($y) | true برای سالهای ۳، ۶، ۸، ۱۱، ۱۴، ۱۷ و ۱۹ از چرخهٔ ۱۹ ساله |
Hebrew::monthsInYear($y) | ۱۲ یا ۱۳ |
Hebrew::daysInYear($y) | ۳۵۳، ۳۵۴، ۳۵۵، ۳۸۳، ۳۸۴ یا ۳۸۵ |
Hebrew::daysInMonth($y, $m) | ۲۹ یا ۳۰. اگر شمارهٔ ماه از تعداد ماههای سال بیشتر باشد، خطا میدهد |
Hebrew::gregorianToHebrew($gy, $gm, $gd) | [سال, ماه ترتیبی, روز] |
Hebrew::hebrewToGregorian($hy, $hm, $hd) | [سال, ماه, روز] |
echo (Hebrew::isLeapYear(5784) ? 'leap' : 'regular'), ' ', (Hebrew::isLeapYear(5785) ? 'leap' : 'regular'); // leap regular
echo Hebrew::daysInYear(5784), ' ', Hebrew::daysInYear(5785), ' ', Hebrew::daysInYear(5786); // 383 355 354
echo json_encode(Hebrew::gregorianToHebrew(2025, 10, 3)); // [5786,1,11]
echo json_encode(Hebrew::hebrewToGregorian(5786, 1, 1)); // [2025,9,23]
ببینید: تبدیل بین تقویمها در تبدیل و مقایسهٔ تاریخها. ماکروهای Carbon (toHebrew() و createFromHebrew()) در ماکروهای Carbon.