العمل المتقدم مع التواريخ والوقت في PHP
\n\nفي تطوير الويب الحديث، تعد المعالجة الصحيحة للتواريخ والوقت ليست مجرد راحة، بل مهمة بالغة الأهمية. سواء كان حساب المواعيد النهائية، تحليل السجلات، العمل مع جمهور عالمي، أو مجرد عرض تاريخ النشر، توفر PHP أدوات قوية ولكنها ليست واضحة دائمًا. في هذه المقالة، سنتجاوز حدود date() و strtotime() الأساسية، لنتعمق في الفئات الموجهة للكائنات والتقنيات المتقدمة التي ستجعل كودك موثوقًا ومرنًا.
المادة موجهة للمطورين الذين هم على دراية بأساسيات PHP بالفعل، ولكنهم يرغبون في تعميق معرفتهم. سنناقش العمل مع المناطق الزمنية، جمع وطرح الفترات، مقارنة التواريخ، وسنتعرف أيضًا على المكتبة الشهيرة Carbon.
\n\n1. الفئة DateTime والفئة DateTimeZone: أساس كل شيء
\n\nبدلاً من الاعتماد على الدوال الإجرائية، تقدم PHP الحديثة استخدام الفئة الموجهة للكائنات DateTime. فهي تغلف كل منطق العمل مع التواريخ والوقت، مما يجعل الكود أكثر قابلية للقراءة وأمانًا.
الميزة الرئيسية لـ DateTime هي إمكانية ربطها بمنطقة زمنية محددة من خلال كائن DateTimeZone. هذا يحل مشكلة الوقت "العائم" عند العمل مع خوادم تقع في مناطق مختلفة.
<?php\n// إنشاء كائن المنطقة الزمنية لموسكو\n$timezone = new DateTimeZone('Europe/Moscow');\n\n// إنشاء كائن DateTime مع تحديد الوقت والمنطقة الزمنية\n$date = new DateTime('2024-12-25 10:00:00', $timezone);\n\necho $date->format('Y-m-d H:i:s'); // سيطبع: 2024-12-25 10:00:00\n?>\n\nإذا لم يتم تحديد المنطقة الزمنية، يستخدم PHP إعدادات الخادم (date.timezone في php.ini). ومع ذلك، للحصول على كود قابل للنقل، من الأفضل دائمًا تحديدها بشكل صريح. يمكن الحصول على قائمة بجميع المناطق الزمنية المتاحة باستخدام DateTimeZone::listIdentifiers().
2. التلاعب بالتواريخ: DateInterval و DatePeriod
\n\nعند الحاجة إلى إضافة أو طرح أيام، أسابيع، أو أشهر، تأتي الفئة DateInterval للإنقاذ. فهي تحدد فترة زمنية يمكن تطبيقها على كائن DateTime.
قد يبدو تنسيق كتابة الفترة (ISO 8601 duration) معقدًا، لكنه مرن جدًا:
- \n
- P — بادئة إلزامية (period). \n
- Y — سنوات، M — أشهر، D — أيام. \n
- T — فاصل للوقت (إذا لزم الأمر). \n
- H — ساعات، M — دقائق، S — ثوانٍ. \n
مثال: P1Y2M3DT4H5M6S يعني سنة واحدة، شهرين، 3 أيام، 4 ساعات، 5 دقائق و 6 ثوانٍ.
<?php\n$date = new DateTime('2024-01-01');\n$interval = new DateInterval('P10D'); // 10 أيام\n\n$date->add($interval);\necho $date->format('Y-m-d'); // سيطبع: 2024-01-11\n\n// العملية العكسية - الطرح\n$date->sub(new DateInterval('P5D'));\necho $date->format('Y-m-d'); // سيطبع: 2024-01-06\n?>\n\nهام: عند العمل مع الأشهر والسنوات، قد يتصرف DateInterval بشكل غير متوقع. على سبيل المثال، إذا أضفت شهرًا واحدًا إلى 31 يناير، فستحصل على 3 مارس (لأن فبراير لا يحتوي على 31 يومًا). للمنطق الأكثر تعقيدًا (مثل "آخر يوم في الشهر")، استخدم الطريقة modify().
تسمح الفئة DatePeriod بإنشاء تسلسلات من التواريخ بسهولة. هذا مثالي لإنشاء التقاويم أو الجداول الزمنية.
<?php\n$start = new DateTime('2024-12-01');\n$end = new DateTime('2024-12-31');\n$interval = new DateInterval('P1W'); // كل أسبوع\n\n$period = new DatePeriod($start, $interval, $end);\n\nforeach ($period as $date) {\n echo $date->format('l, Y-m-d') . "\\n"; // سيطبع جميع أيام الإثنين في ديسمبر\n}\n?>\n\n