هذا المقال يتطلب مستوى: مبتدئ
لو الموعد اللي خزّنته الساعة 3 بيظهر لمستخدم في بلد تاني الساعة 5، المشكلة مش في السيرفر ولا في المستخدم. انت بتخزّن وقت من غير ما تقول هو بأي منطقة زمنية. المقال ده هيخلّيك تخزّن الوقت صح مرة واحدة وتريّح دماغك.
التوقيت وUTC: ليه الوقت بيلعب في تطبيقك
المشكلة باختصار
أغلب التطبيقات بتخزّن التاريخ كنص زي 2026-07-16 15:00 من غير أي إشارة لمنطقة زمنية. الرقم ده لوحده مالوش معنى. 15:00 في القاهرة مش نفس 15:00 في الرياض ولا في لندن. لمّا مستخدم في منطقة تانية يفتح نفس البيانات، تطبيقك بيخمّن المنطقة غلط، فالموعد بيتزحلق ساعة أو اتنين.
المفهوم بمثال بسيط
تخيّل إنك اتفقت مع صاحبك على مكالمة وقلتله "نتكلم الساعة 8". انت في القاهرة وهو في لندن. لو كل واحد فهم "8 بتوقيت بلده"، هتقعد تستنى ساعتين وهو نايم. الحل إنكم تتفقوا على مرجع واحد ثابت للكل: "نتكلم الساعة 8 بتوقيت جرينتش". كل واحد يحوّلها لتوقيت بلده بنفسه وقت المكالمة بس.
الـ UTC هو نفس الفكرة دي بالظبط في الكود. هو التوقيت العالمي المنسّق، مرجع واحد ثابت لكل الكوكب لا يتأثر بالتوقيت الصيفي. القاعدة: خزّن كل لحظة بالـ UTC، وحوّلها لتوقيت المستخدم وقت العرض بس.
الشرح العلمي الدقيق
في البرمجة فيه نوعين من الوقت. الأول اسمه naive، يعني رقم وقت من غير منطقة زمنية ملصوقة بيه. الرقم ده غامض لأنه مش عارف هو بيقيس من أي نقطة. النوع التاني اسمه aware، يعني وقت شايل معاه منطقته الزمنية، فبيحدّد لحظة واحدة على الكوكب من غير أي لبس.
المناطق الزمنية نفسها مش ثابتة. كتير من الدول بتقدّم الساعة ساعة في الصيف وترجّعها في الشتا، وده اللي اسمه التوقيت الصيفي (DST). ده معناه إن الفرق بين بلدك والـ UTC ممكن يتغيّر مرتين في السنة. عشان كده فيه قاعدة بيانات رسمية اسمها IANA Time Zone Database بتسجّل كل التغييرات دي لكل منطقة، وأي لغة محترمة بتعتمد عليها بدل ما تحسب الفرق بنفسها.
الحل: خطوات عملية
- خزّن كل الأوقات في قاعدة البيانات بالـ UTC، ومعاها المنطقة الزمنية دايمًا.
- استقبل من المستخدم منطقته الزمنية باسمها (زي
Africa/Cairo)، مش بفرق الساعات، عشان التوقيت الصيفي يتحسب صح. - حوّل من UTC لتوقيت المستخدم في لحظة العرض بس، مش قبل كده.
- لو بتبعت الوقت بين أنظمة، استخدم صيغة ISO 8601 اللي بتشيل المنطقة جواها زي
2026-07-16T13:00:00Z.
الكود ده بيوريك الفرق بين الطريقة الغلط والصح في بايثون (نسخة 3.9 أو أحدث):
from datetime import datetime, timezone
from zoneinfo import ZoneInfo # مدمج في بايثون 3.9+
# غلط: وقت بدون منطقة زمنية (naive) — غامض
naive = datetime(2026, 7, 16, 15, 0)
print(naive) # 2026-07-16 15:00:00 --> 15:00 فين بالظبط؟ محدش عارف
# صح: خزّن اللحظة بالـ UTC (aware)
utc_time = datetime(2026, 7, 16, 13, 0, tzinfo=timezone.utc)
# اعرض حسب منطقة كل مستخدم وقت العرض بس
cairo = utc_time.astimezone(ZoneInfo("Africa/Cairo"))
riyadh = utc_time.astimezone(ZoneInfo("Asia/Riyadh"))
london = utc_time.astimezone(ZoneInfo("Europe/London"))
print("القاهرة:", cairo.strftime("%H:%M")) # 16:00
print("الرياض:", riyadh.strftime("%H:%M")) # 16:00
print("لندن:", london.strftime("%H:%M")) # 14:00