في هذا الدرس 6تصفّح المواضيع
تخزن تطبيقات PHP الاحترافية الأوقات بالتوقيت العالمي UTC، ثم تحولها عند العرض إلى المنطقة الزمنية للمستخدم عبر timezone_open() وdate_timezone_set().
- اضبط المنطقة الزمنية الافتراضية للسكريبت عند بدء التشغيل عبر
date_default_timezone_set("UTC")وتحقق منها عبرdate_default_timezone_get(). - أنشئ كائن المنطقة الزمنية بالدالة
timezone_open("Asia/Riyadh")ومرّره إلىdate_create_immutable()أوdate_timezone_set(). - بما أن
date_create_immutable()تنشئ تاريخاً غير قابل للتعديل المباشر، فإنdate_timezone_set($dt, $tz)تُرجع نسخة جديدة محولة دون تغيير الأصل.
يتم تحويل اللحظة الزمنية نفسها (12:00 +00:00 بتوقيت UTC) بدقة إلى 15:00 +03:00 بتوقيت الرياض.
<?php
date_default_timezone_set('UTC');
$utc = date_create_immutable('2026-05-01 12:00:00', timezone_open('UTC'));
$riyadh = date_timezone_set($utc, timezone_open('Asia/Riyadh'));
echo "UTC: " . date_format($utc, 'H:i P') . "\n";
echo "Riyadh: " . date_format($riyadh, 'H:i P') . "\n";
تحول الدالة strtotime() العبارات الزمنية النسبية مثل "+2 weeks" أو "first day of next month" إلى طابع زمني بالثواني (Unix Timestamp).
- مرّر طابعاً زمنياً مرجعياً كمعامل ثانٍ
strtotime("+10 days", $baseTs)لجعل الحسابات النسبية ثابتة وقابلة للاختبار. - تُرجع
strtotime()القيمةfalseإذا تعذر تحليل النص المدخل كتاريخ صالح. - انتبه لفرق الفاصل النصي: الصيغة بالشرطة المائلة
"05/04/2026"تُفسر كـشهر/يوم/سنة، بينما الشرطة العادية"05-04-2026"تُفسر كـيوم-شهر-سنة.
بالاعتماد على تاريخ الأساس 2026-03-15، تعطي إضافة 14 يوماً التاريخ 2026-03-29، ويعطي أول يوم في الشهر التالي 2026-04-01.
<?php
date_default_timezone_set('UTC');
$base = strtotime('2026-03-15 00:00:00');
$trialEnd = strtotime('+14 days', $base);
$nextMonth = strtotime('first day of next month', $base);
echo "Trial ends: " . date('Y-m-d', $trialEnd) . "\n";
echo "Next billing: " . date('Y-m-d', $nextMonth) . "\n";
استخدم الدالة date_interval_create_from_date_string() مع date_add() وdate_sub() لإضافة أو طرح الفترات الزمنية دون التأثير على التاريخ الأصلي.
- تبني الدالة
date_interval_create_from_date_string("1 month + 5 days")فترة زمنية مهيكلة من عبارة واضحة. - عند تطبيقها عبر
date_add($dt, $interval)على تاريخ غير قابل للتعديل، يبقى المتغير الأصلي$dtثابتاً وتُرجع الدالة تاريخاً جديداً. - يمكنك أيضاً إزاحة التاريخ مباشرة عبر الدالة
date_modify($dt, "+3 hours").
إضافة شهر و5 أيام إلى 2026-01-10 تعطي 2026-02-15، وطرح 3 أيام يحدد موعد التذكير في 2026-02-12.
<?php
date_default_timezone_set('UTC');
$issued = date_create_immutable('2026-01-10 09:00:00');
$span = date_interval_create_from_date_string('1 month + 5 days');
$due = date_add($issued, $span);
$reminder = date_sub($due, date_interval_create_from_date_string('3 days'));
echo "Issued: " . date_format($issued, 'Y-m-d') . " | Due: " . date_format($due, 'Y-m-d') . " | Remind: " . date_format($reminder, 'Y-m-d') . "\n";
لا تطرح الطوابع الزمنية وتقسمها على 86400 عبر الشهور المختلفة؛ بل اعتمد على date_diff($start, $end) لحساب الفروق التقويمية بدقة.
- تُرجع
date_diff($d1, $d2)كائن فترة يحتوي على الخصائصy(السنوات) وm(الشهور) وd(الأيام المتبقية) وإجمالي الأيام الكليdays. - تعطي الخاصية
$diff->daysإجمالي عدد الأيام الكلي بين التاريخين، بينما تعطي$diff->dالأيام المتبقية فقط بعد خصم الشهور الكاملة. - نسّق الفارق عبر
date_interval_format($diff, "%R%a days")حيث يطبع%Rالإشارة (+أو-) ويطبع%aإجمالي الأيام.
بين 1 يناير و5 مارس 2026، تحسب date_diff() التفصيل التقويمي (2 months, 4 days) وإجمالي الأيام الكلي (63 days).
<?php
date_default_timezone_set('UTC');
$start = date_create_immutable('2026-01-01');
$end = date_create_immutable('2026-03-05');
$diff = date_diff($start, $end);
$breakdown = date_interval_format($diff, '%m months, %d days');
echo "$breakdown (Total: " . $diff->days . " days)\n";
لتوليد تواريخ الفوترة الدورية أو المواعيد الأسبوعية المتكررة بين تاريخين، تقدم بخطوات ثابتة باستخدام تاريخ البداية والفترة الزمنية.
- في PHP 8.2+ يمكن توليد السلاسل الزمنية المتكررة وفق صيغة التكرار القياسية ISO-8601 أو بالتقدم الدوري عبر فترة ثابتة.
- في السكريبتات الإجرائية، يتيح تحريك المؤشر الزمني عبر
date_add($cursor, $step)داخل حلقةforأوwhileتوليد المواعيد الدورية بدقة. - تحافظ الفترات التقويمية مثل
"7 days"أو"1 month"على ثبات الساعة المحلية حتى عند تغير التوقيت الصيفي.
بدءاً من 2026-04-01، تسجل كل دورة التاريخ المنسق وتُقدم المؤشر $cursor بمقدار 7 أيام.
<?php
date_default_timezone_set('UTC');
$cursor = date_create_immutable('2026-04-01');
$step = date_interval_create_from_date_string('7 days');
$slots = [];
for ($i = 0; $i < 4; $i++) {
$slots[] = date_format($cursor, 'Y-m-d');
$cursor = date_add($cursor, $step);
}
echo implode(' -> ', $slots) . "\n";
تبدأ نصوص الفترات القياسية ISO 8601 بالحرف P لوحدات التاريخ، وتستخدم الحرف T للفصل قبل وحدات الوقت (الساعات والدقائق والثواني).
- انتبه للفرق الدقيق بين
P1M(شهر واحد في قسم التاريخ) وPT1M(دقيقة واحدة بعد فاصل الوقتT). - في دالة التنسيق
date_interval_format()تبدأ الرموز بالعلامة%مثل%yللسنوات و%mللشهور و%dللأيام و%aلإجمالي الأيام. - فضّل دائماً التواريخ غير القابلة للتعديل المباشر (
date_create_immutable()) لمنع التعديل الجانبي غير المقصود على التواريخ المشتركة.
تنسق الدالة date_interval_format() الفارق الزمني بين التاريخين على صورة 2 days, 6 hrs, 30 mins.
| رمز ISO 8601 / التنسيق | المعنى | مثال عملي | الخطأ الشائع |
|---|---|---|---|
P1Y2M10D | 1 Year, 2 Months, 10 Days | Date period units | Missing leading P |
PT4H30M | 4 Hours, 30 Minutes | Time units after T | Writing P30M (30 months!) instead of PT30M |
%a vs %d | Total days vs Remainder days | 63 vs 4 | Using %d when total days is needed |
%R | Sign (+ or -) | %R%a -> +63 | Forgetting to check if $diff->invert === 1 |
<?php
date_default_timezone_set('UTC');
$d1 = date_create_immutable('2026-06-01 08:00:00');
$d2 = date_create_immutable('2026-06-03 14:30:00');
$diff = date_diff($d1, $d2);
echo date_interval_format($diff, '%a days, %h hrs, %i mins') . "\n";
ملخص الدرس
حصاد الدرسمراجعة مركّزة لأهم المفاهيم والقواعد الهندسية التي أتقنتها في هذا الدرس قبل التطبيق العملي
ماذا تعلّمت في هذا الدرس؟
تبدأ نصوص الفترات القياسية ISO 8601 بالحرف P لوحدات التاريخ، وتستخدم الحرف T للفصل قبل وحدات الوقت (الساعات والدقائق والثواني). انتبه للفرق الدقيق بين P1M (شهر واحد في قسم التاريخ) وPT1M (دقيقة واحدة بعد فاصل الوقت T). في دالة التنسيق date_interval_format() تبدأ الرموز بالعلامة % مثل %y للسنوات و%m للشهور و%d للأيام و%a لإجمالي الأيام. فضّل دائماً التواريخ غير القابلة للتعديل المباشر (date_create_immutable()) لمنع التعديل الجانبي غير المقصود على التواريخ المشتركة.
سجّل الدخول لحفظ تقدمك
تابع إنجاز المواضيع والمصطلحات والمهام، وكمّل من آخر خطوة على أي جهاز.
المصطلحات4
راجع المعنى، اشرحه لنفسك، ثم علّم البطاقة كمفهومة.
- 01 Date Diff & Timezones الفروق والمناطق الزمنية
- احسب الفروق الزمنية بدقة، وأضف واطرح الفترات عبر DateTimeImmutable وDateInterval، وحوّل التوقيت بين المناطق الزمنية المختلفة في PHP 8.
- للمراجعة
- 02 Configuring Timezones with DateTimeZone ضبط وتحويل المناطق الزمنية عبر DateTimeZone
- المفهوم الأساسي لقسم ضبط وتحويل المناطق الزمنية عبر DateTimeZone في لغة PHP الحديثة.
- للمراجعة
- 03 Parsing Relative Dates with strtotime تحليل التواريخ النسبية والنصية بدالة strtotime
- الصياغة البرمجية والتطبيق العملي المباشر لقسم تحليل التواريخ النسبية والنصية بدالة strtotime.
- للمراجعة
- 04 Adding and Subtracting with DateInterval إضافة وطرح الفترات الزمنية بـ DateInterval
- قواعد التحقق وأفضل الممارسات القياسية الخاصة بقسم إضافة وطرح الفترات الزمنية بـ DateInterval.
- للمراجعة
لا توجد بطاقات تطابق البحث والتصفية.
اقرأ البطاقات بحرية. سجّل الدخول لحفظ تقدم مراجعتك.
الاختصارات4
راجع المعنى، اشرحه لنفسك، ثم علّم البطاقة كمفهومة.
- 01 PHP PHP
- PHP: Hypertext Preprocessor
- لغة البرمجة النصية على جانب الخادم لبناء تطبيقات الويب الديناميكية وواجهات البرمجة.
- للمراجعة
- 02 CLI CLI
- Command-Line Interface
- واجهة سطر الأوامر التي تتيح تشغيل ملفات PHP مباشرة عبر الطرفية.
- للمراجعة
- 03 FPM FPM
- FastCGI Process Manager
- مدير عمليات FastCGI عالي الأداء لمعالجة طلبات خادم الويب في PHP.
- للمراجعة
- 04 HTML HTML
- HyperText Markup Language
- لغة الترميز القياسية التي يولدها محرك PHP ويرسلها إلى متصفح العميل بعد التنفيذ.
- للمراجعة
لا توجد بطاقات تطابق البحث والتصفية.
اقرأ البطاقات بحرية. سجّل الدخول لحفظ تقدم مراجعتك.
مهامك قبل الاختبار
خطوة صغيرة كل مرة. وإنجاز تقدر ترجع له.
-
أنشئ ملف PHP محلياً ونفّذ المثال البرمجي المشروح في قسم ضبط وتحويل المناطق الزمنية عبر DateTimeZone للتحقق من المخرجات.
-
بدّل بين الحالات الثلاث في المحاكي التفاعلي ضمن قسم تحليل التواريخ النسبية والنصية بدالة strtotime وقارن مخرجات التنفيذ.
تأشير المهمة إقرار منك بإتمامها، وليس تصحيحًا آليًا للكود. يُحفظ تقدمك في حسابك.
اختبر فهمك.
ووصلها للإتقان.
كل سؤال خطوة لقدّام. اختار، اكتب كود، وشوف نتيجتك فورًا.
أكمل المهام، واجمع كل الإجابات الصحيحة. أقل من 100%؟ راجع وأعد المحاولة.
الأسئلة متاحة للاطلاع. سجّل الدخول للتفاعل وحفظ تقدمك.
لمحة عن التحدي8 أسئلة تنتظرك +
لماذا يجب تخزين الأوقات في قاعدة البيانات بتوقيت UTC وتحويلها للمنطقة الزمنية المحلية عند العرض فقط؟
توقيت UTC ثابت عالمياً ولا يتغير بالتوقيت الصيفي مما يضمن دقة الترتيب والحسابات.
ما الميزة الجوهرية للدالة date_create_immutable() مقارنةً بـ date_create() عند استدعاء date_add() أو date_timezone_set()؟
عدم القابلية للتعديل يمنع الأخطاء الجانبية الخفية عند تمرير التواريخ بين أجزاء الكود.
في نتيجة الدالة date_diff($d1, $d2)، ما الفرق بين الخاصية $diff->days والخاصية $diff->d؟
في فترة شهرين و4 أيام، تكون $diff->days مساوية لـ 63 بينما $diff->d تساوي 4 فقط.
في صيغة الفترات القياسية ISO 8601، ما الفرق بين "P5M" و"PT5M"؟
حرف M قبل T يرمز للشهور، وبعد فاصل الوقت T يرمز للدقائق.
ماذا تُرجع الدالة strtotime("invalid date text") عند تمرير نص لا يمثل تاريخاً صالحاً؟
تُرجع الدالة strtotime() القيمة false عند فشل التحليل.
أي رمز تنسيق في دالة date_interval_format() يطبع إجمالي عدد الأيام الكلي بين تاريخين؟
يطبع الرمز %a إجمالي عدد الأيام الكلي المحسوب عبر date_diff().
كيف تفسر الدالة strtotime() التاريخ "10/04/2026" (بالشرطة المائلة) مقابل "10-04-2026" (بالشرطة العادية)؟
تعتمد strtotime() على نوع الفاصل، ولذلك يُنصح دائماً بصيغة ISO القياسية YYYY-MM-DD.
ما الدالة التي تضبط المنطقة الزمنية الافتراضية لجميع دوال التاريخ والوقت في السكريبت الحالي؟
تضبط date_default_timezone_set() المنطقة الزمنية الافتراضية وقت التشغيل.