التقويم العبري

فئة التاريخ العبري (اليهودي) غير القابلة للتغيير، بترقيم ترتيبي للأشهر وآدار الأول والثاني في السنة الكبيسة، وأسماء الأشهر بالإنجليزية والعبرية والفارسية: إنشاء التواريخ وتحليلها وتنسيقها وإزاحتها وقياسها.

في هذه الصفحة
  1. ما الذي تفعله الفئة
  2. ترقيم الأشهر
  3. إنشاء التواريخ
    1. دلالات السلاسل النصية
  4. النطاق المدعوم والأخطاء
  5. قراءة القيم
    1. ترقيم أيام الأسبوع
  6. التنسيق
  7. الإزاحة والضبط
  8. المقارنة والقياس
  9. الحساب التقويمي

ما الذي تفعله الفئة#

RtlyKit\Calendar\Hebrew هي قيمة تاريخ ووقت لا تتغير بعد إنشائها، في التقويم العبري (اليهودي). كُتبت بـ PHP الخالص (دون ext-calendar) وتنفّذ التقويم الحسابي الثابت: مولد تِشري (molad)، وتأجيلات dehiyyot الأربعة، وأطوال السنوات 353 و354 و355 يومًا للسنة العادية و383 و384 و385 يومًا للسنة الكبيسة. وكبقية التقويمات، تحتفظ بلحظة واحدة من النوع 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');
من المفيد أن تعرف. يبدأ اليوم العبري عند الغروب، أما هذه الفئة فتغيّر التاريخ عند منتصف الليل المدني، مثل بقية تقويمات المكتبة. لذلك فإن ما بعد الغروب (كمساء ليلة العطلة) يُنسب دينيًا إلى التاريخ العبري التالي، لكنه يبقى هنا على تاريخ يومه المدني. والفئة لا تحسب العطل، ولا الفقرات الأسبوعية من التوراة (parashot)، ولا عدّ العومر.

ترقيم الأشهر#

تُرقَّم الأشهر بحسب موضعها الترتيبي في السنة بدءًا من تِشري (رأس السنة المدنية). وفي السنة الكبيسة يكون آدار الأول وآدار الثاني شهرين منفصلين:

  • الأشهر من 1 إلى 5 هي دائمًا: Tishrei وCheshvan وKislev وTevet وShevat.
  • السنة العادية: 6 = Adar، 7 = Nisan، 8 = Iyar، 9 = Sivan، 10 = Tammuz، 11 = Av، 12 = Elul.
  • السنة الكبيسة: 6 = Adar I، 7 = Adar II، 8 = Nisan، 9 = Iyar، 10 = Sivan، 11 = Tammuz، 12 = Av، 13 = Elul.
ترقيم يختلف عن Hebcal. يختلف هذا الترقيم عن Hebcal (حيث Nisan = 1) وعن ext-calendar في PHP. فشهر Elul هو الشهر 12 في السنة العادية و13 في الكبيسة، وشهر Nisan هو الشهر 7 أو 8. خذ أرقام الأشهر من 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)؛ وفي السنة العادية يكون الموضع 6 هو Adar البسيط.

إنشاء التواريخ#

تتحقق Hebrew::create($year, $month, $day, $hour = 0, $minute = 0, $second = 0, $timezone = null) من التاريخ بحسب الطول الفعلي لذلك الشهر في تلك السنة (يتراوح Cheshvan وKislev بين 29 و30 يومًا).

$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  (15 Nisan 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، أو طابعًا زمنيًا من النوع int، أو سلسلة نصية، أو 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

دلالات السلاسل النصية#

  1. تتحول الأرقام الفارسية والعربية إلى أرقام إنجليزية؛ وتُقصّ المسافات من الطرفين؛ والسلسلة الفارغة تُطلق InvalidDateException.
  2. السلسلة بالصيغة Y/m/d أو Y-m-d (وH:i[:s] اختياري) وسنتها 3000 أو أكثر تُقرأ تاريخًا عبريًا، بالترقيم الترتيبي للأشهر الموصوف أعلاه. (العتبة معاكسة لما في Jalali وHijri اللذين يقرآن السنوات الأقل من 1700 تاريخًا لهما.)
  3. كل سلسلة أخرى تُحلَّل تاريخًا ميلاديًا أو نصًا حرًّا.

فـ '5785/01/10' عبري، و'2025-10-07' ميلادي، أما '3000/01/01' فتُقرأ سنة عبرية 3000 وهي أقل من الحد الأدنى المدعوم، ولذلك تُطلق Invalid Hebrew date: 3000/1/1.

النطاق المدعوم والأخطاء#

السنوات العبرية المدعومة من Hebrew::MIN_YEAR = 3762 إلى Hebrew::MAX_YEAR = 13759. وهي بالضبط السنوات الواقعة داخل السنوات الميلادية من 1 إلى 9999: أول يوم هو 1 Tishrei 3762 (0001-09-06) وآخر يوم هو آخر يوم من Elul 13759 (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 is a regular year: 12 months)
// Invalid Hebrew date: 5785/3/31

echo Hebrew::create(5784, 13, 1) instanceof Hebrew ? 'ok' : '';   // ok  (5784 is a leap year)

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() السنوات من 1 إلى 13759 (السنة 0 تُطلق Hebrew year out of the supported range: 0)؛ ولا يستخدم الحدَّ الأدنى الأضيق 3762 إلا إنشاء التواريخ.

قراءة القيم#

دوال القراءة هي دوال العقد (getYear() وgetMonth() وgetDay() وأجزاء الوقت وgetTimestamp() وgetTimezone() وtoGregorian() وtoDateString() وtoDateTimeString()). والدالة getMonth() تُرجع الشهر الترتيبي الموصوف أعلاه.

ترقيم أيام الأسبوع#

تبدأ getDayOfWeek() والرمز w من الأحد: 0 = الأحد إلى 6 = السبت (مثل Hijri وPHP، وخلافًا لـ Jalali). والرمز N هو الرقم بحسب ISO (الاثنين = 1).

echo $e->getDayOfWeek();   // 4   (كان 1 Tishrei 5785 يوم خميس)
foreach (range(0, 6) as $i) { echo $e->addDays($i)->getDayOfWeek(); }  // 4560123

التنسيق#

format($pattern = 'Y/m/d H:i:s', $locale = 'en') حيث $locale إحدى القيم en أو he أو fa. الأرقام لاتينية دائمًا. وتُبطل الشرطة المائلة العكسية المعنى الخاص للمحرف الذي يليها.

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الوقت من اليوم (نظام 24 ساعة و12 ساعة)
F Mاسم الشهر بحسب اللغة (Adar I/II أو Adar بحسب الحال)
lاسم يوم الأسبوع بحسب اللغة
w Nالأحد = 0؛ والاثنين بحسب ISO = 1
z t Lرقم اليوم في السنة بدءًا من الصفر؛ وعدد أيام الشهر؛ و1 للسنة الكبيسة (13 شهرًا)
a Aam/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تُفوَّض إلى اللحظة الأساسية

الإزاحة والضبط#

الدوال هي نفسها في Jalali. وهناك قاعدتان خاصتان بالتقويم العبري لهما أهميتهما:

  • الأشهر تُعدّ أشهرًا ترتيبية، ويُعدّ آدار الأول وآدار الثاني شهرين منفصلين؛ ويُقصَّر اليوم إلى طول الشهر الهدف. والعمل محدود (دورات كاملة من 19 سنة، ثم 19 خطوة سنوية على الأكثر)، ولا يتوقف على كِبَر قيمة $months.
  • السنوات تحافظ على الشهر «نفسه»: فالانتقال من سنة كبيسة إلى سنة عادية يحوّل Adar I وAdar II إلى Adar؛ والانتقال من سنة عادية إلى كبيسة يحوّل Adar إلى Adar II.
$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() الأشهر العبرية الكاملة (ويُحتسب Adar I وAdar II منفصلين)؛ وتعتمد diffInYears() على الذكرى السنوية (فالسنة العبرية فيها 12 أو 13 شهرًا، فليست عدد الأشهر مقسومًا على 12).

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)صحيحة للسنوات 3 و6 و8 و11 و14 و17 و19 من الدورة ذات الـ 19 سنة
Hebrew::monthsInYear($y)12 أو 13
Hebrew::daysInYear($y)353 أو 354 أو 355 أو 383 أو 384 أو 385
Hebrew::daysInMonth($y, $m)29 أو 30؛ وتُطلق استثناءً لشهر يتجاوز عدد أشهر السنة
Hebrew::gregorianToHebrew($gy, $gm, $gd)[year, ordinalMonth, day]
Hebrew::hebrewToGregorian($hy, $hm, $hd)[year, month, day]
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.