المستوى المطلوب: مبتدئ. المقال ده لأي حد بيبني تطبيق فيه مواعيد أو تواريخ، حتى لو لسه بادئ. مش محتاج تكون خبير قواعد بيانات، بس محتاج تكون كتبت كود بيخزّن تاريخ أو وقت قبل كده.
ليه ميعاد الاجتماع بيظهر بالساعة الغلط؟ سرّ تخزين الوقت بالـ UTC
لو خزّنت وقت اجتماع ولقيته بيظهر مضبوط عندك وغلط عند مستخدم في بلد تانية، المشكلة مش في السيرفر ولا في المستخدم. المشكلة إنك خزّنت الوقت بالتوقيت المحلي بدل ما تخزّنه موحّد. المقال ده هيوريك أفضل طريقة تتعامل بيها مع الوقت في أي تطبيق: خزّن بالـ UTC، وحوّل وقت العرض بس.
المشكلة باختصار
عندك تطبيق مواعيد. مستخدم في القاهرة حجز اجتماع الساعة 3 عصرًا. التطبيق خزّن الرقم "15:00" في الداتابيز من غير ما يسجّل إن ده توقيت القاهرة. زميله في لندن فتح نفس الاجتماع، والتطبيق عرض "15:00" برضه. النتيجة: زميل لندن حضر الساعة 3 بتوقيت لندن، واللي هو أصلًا 5 عصرًا في القاهرة. الاجتماع ضاع، والسبب سطر تخزين واحد.
المفهوم الأساسي بمثال بسيط
تخيّل إنك اتفقت مع صحابك تتقابلوا "بعد ما الشمس تغرب". المشكلة إن الشمس بتغرب في وقت مختلف في كل مدينة. الجملة دي غامضة لأنها مربوطة بمكان كل واحد. لكن لو اتفقتوا "نتقابل لما ساعة مكة تدق 8"، بقى عندكم مرجع واحد ثابت الكل بيرجعله، وكل واحد يحسب الفرق بينه وبين مكة.
الـ UTC هو بالظبط "ساعة مكة" دي بس للعالم كله. هو توقيت مرجعي واحد، ثابت، مالوش صيف ولا شتا، وكل مناطق العالم الزمنية بتتحسب كإزاحة منه: القاهرة UTC+2 أو UTC+3 في الصيف، لندن UTC+0 أو UTC+1، اليابان UTC+9. لو خزّنت كل حاجة بالـ UTC، بتبقى ماسك المرجع الثابت، والتحويل لأي مدينة بقى مجرد جمع أو طرح.
المفهوم علميًا وبدقة
الـ UTC اختصار لـ Coordinated Universal Time، وهو معيار التوقيت العالمي اللي كل الأنظمة بتزامن عليه. اللحظة الزمنية الحقيقية (instant) حاجة واحدة موجودة في الكون كله في نفس اللأنية. اللي بيختلف هو تمثيلها على ساعة الحائط في كل مكان. لما تخزّن "15:00" من غير منطقة زمنية، انت خزّنت تمثيل بدون مرجعه، فبقى الرقم بلا معنى مؤكد.
القاعدة الذهبية: خزّن اللحظة الزمنية بالـ UTC، اعرض بالتوقيت المحلي، احسب بالـ UTC. التحويل للتوقيت المحلي يحصل في آخر خطوة قبل ما تعرض للمستخدم بس، ومايتخزّنش أبدًا في الداتابيز كقيمة أساسية.
الحل بالكود
الخطأ الشائع في بايثون هو استخدام datetime.now() اللي بترجّع وقت "ساذج" (naive) من غير منطقة زمنية. البديل الصح هو وقت "واعي" (aware) مربوط بالـ UTC. الكود ده يوريك الفرق والحل: