مقدمة: لماذا الوقت مشكلة حقيقية؟
\n\nتخيل: أنت تبني متجرًا إلكترونيًا. عميل من نيويورك يقدم طلبًا في الساعة 3:00 عصرًا بتوقيته المحلي. تقوم بحفظ التاريخ في قاعدة البيانات. ثم يقرر الخادم الموجود في موسكو أن الطلب تم في الساعة 10:00 مساءً. وتبدأ الفوضى: تأخر التوصيل، اختلاف التقارير، غضب العملاء.
\n\nموقف مألوف؟ مرحبًا بك في عالم المناطق الزمنية في PHP. هذا الموضوع يمثل تحديًا حقيقيًا للمبتدئين وحتى للمطورين المحترفين. لكن الخبر السار: إذا فهمت الأمر مرة واحدة وأعددت كل شيء بشكل صحيح، ستنسى مشاكل الوقت إلى الأبد.
\n\nفي هذا المقال، سنشرح كيفية العمل مع المناطق الزمنية في PHP، وكيفية تجنب أخطاء التوقيت الصيفي، ولماذا UTC هو أفضل صديق لك. هيا بنا!
\n\nالإعداد العام للمنطقة الزمنية في PHP
\n\nالخطوة الأولى والأهم هي التأكد من أن PHP يعرف المنطقة الزمنية التي يعمل بها خادمك. يتم ذلك عبر توجيه date.timezone في ملف php.ini أو مباشرة في الكود باستخدام الدالة date_default_timezone_set().
// تعيين المنطقة الزمنية للسكريبت بأكمله\ndate_default_timezone_set('Asia/Riyadh');\n\necho date('Y-m-d H:i:s'); // يعرض الوقت الحالي بتوقيت الرياض\n\nلكن انتبه! إذا كنت تتعامل مع مستخدمين من دول مختلفة، تثبيت منطقة زمنية واحدة للمشروع بأكمله فكرة سيئة. الأفضل دائمًا تخزين الوقت بصيغة UTC (التوقيت العالمي المنسق) وتحويله حسب المنطقة الزمنية لكل مستخدم.
\n\nالتحقق من المنطقة الزمنية الحالية
\n\nمن المفيد دائمًا معرفة المنطقة الزمنية المحددة حاليًا:
\n\necho date_default_timezone_get(); // مثال: 'Asia/Riyadh'\n\nكائن DateTimeZone - أداتك الأساسية
\n\nفي PHP، يوجد كائن قوي يسمى DateTimeZone. يتيح لك التعامل مع المناطق الزمنية ككيانات مستقلة. لنلقِ نظرة على مثال أساسي:
\n\n$timezone = new DateTimeZone('America/New_York');\n$datetime = new DateTime('now', $timezone);\n\necho $datetime->format('Y-m-d H:i:s'); // الوقت الحالي في نيويورك\n\nلاحظ أننا مررنا المنطقة الزمنية مباشرة إلى مُنشئ DateTime. هذه هي أنظف طريقة للعمل مع المناطق الزمنية في PHP.
قائمة بجميع المناطق الزمنية المتاحة
\n\nهل تريد معرفة المناطق الزمنية التي يدعمها PHP؟ استخدم الدالة listIdentifiers():
$zones = DateTimeZone::listIdentifiers();\necho count($zones); // حوالي 400+ منطقة!\n\n// عرض أول 10 مناطق\nprint_r(array_slice($zones, 0, 10));\n\nهذه القائمة ضخمة. لكن لا تحتاج لحفظها كلها - يكفي أن تعرف المعرفات القياسية مثل Asia/Riyadh أو Europe/London أو UTC.
التحويل بين المناطق الزمنية
\n\nالمهمة الأكثر شيوعًا: أخذ وقت من منطقة زمنية وتحويله إلى أخرى. في PHP، يتم ذلك بسهولة عبر الدالة setTimezone().
// الوقت بصيغة UTC\n$utcTime = new DateTime('2025-03-15 12:00:00', new DateTimeZone('UTC'));\n\n// التحويل إلى توقيت طوكيو\n$tokyoTime = clone $utcTime;\n$tokyoTime->setTimezone(new DateTimeZone('Asia/Tokyo'));\n\necho $utcTime->format('Y-m-d H:i:s') . ' UTC'; // 2025-03-15 12:00:00 UTC\necho ' = ';\necho $tokyoTime->format('Y-m-d H:i:s') . ' Tokyo'; // 2025-03-15 21:00:00 Tokyo\n\nلاحظ أننا استخدمنا clone لتجنب تغيير الكائن الأصلي. إذا لم تفعل ذلك، سيتحول الوقت الأصلي أيضًا إلى توقيت طوكيو.
أفضل ممارسة: خزّن كل شيء بصيغة UTC
\n\nالقاعدة الذهبية في تطوير الويب: احفظ دائمًا التواريخ والأوقات بصيغة UTC. قاعدة البيانات، ذاكرة التخزين المؤقت، السجلات - كل شيء بصيغة UTC. وقم بالتحويل حسب المستخدم فقط عند عرض البيانات.
\n\n// حفظ في قاعدة البيانات (مثال)\n$nowUTC = new DateTime('now', new DateTimeZone('UTC'));\n$db->query("INSERT INTO orders (created_at) VALUES ('" . $nowUTC->format('Y-m-d H:i:s') . "')");\n\nبهذه الطريقة، ستتجنب كل مشاكل المناطق الزمنية والتوقيت الصيفي. وعند العرض، يمكنك تحويل الوقت بسهولة:
\n\n// عرض الوقت حسب المنطقة الزمنية للمستخدم\n$userTimezone = new DateTimeZone('America/New_York');\n$orderTime = new DateTime($row['created_at'], new DateTimeZone('UTC'));\n$orderTime->setTimezone($userTimezone);\necho $orderTime->format('Y-m-d H:i:s');