
تنسخ قيمة مثل 1760000000 فتتحول إلى تاريخ منطقي. تنسخ قيمة أخرى مثل 1760000000000 فتظهر أيضًا كتاريخ منطقي في أداة أخرى. الفرق غالبًا ليس “Timestamp قديم وجديد”، بل الوحدة: ثوانٍ مقابل مللي ثانية.
فهم Epoch والوحدة
ما هو Epoch الذي نعد منه؟
POSIX يعرّف مفهوم “Seconds Since the Epoch” كقيمة مرتبطة بعدد الثواني منذ بداية الحقبة المرتبطة بـ1 يناير 1970. كما يفترض في هذا الحساب أيامًا من 86400 ثانية ولا يطبق leap seconds كعد إضافي في قيمة POSIX time. [المصدر: The Open Group — POSIX]
الفكرة العملية: بدل تخزين «3 سبتمبر الساعة 14:30 بتوقيت كذا» كنص فقط، يمكن للنظام الاحتفاظ بقيمة عددية تشير إلى لحظة بالنسبة إلى Epoch، ثم يعرضها بصيغة بشرية عند الحاجة.
1760000000
في الزمن الحالي غالبًا ترى قيمًا من نحو 10 أرقام عندما تكون الوحدة seconds.
1760000000000
في JavaScript Date والقيم الحالية، تمثيل milliseconds يكون غالبًا نحو 13 رقمًا.
10 أرقام و13 رقمًا قاعدة عملية وليست تعريفًا رسميًا
طول الرقم يتغير مع الحقبة والزمن. لذلك لا تقل «كل Timestamp من 10 أرقام ثوانٍ دائمًا» كقاعدة أبدية. هو heuristic مفيد جدًا للقيم الحديثة، وليس جزءًا من تعريف POSIX نفسه.
الأداة في تولاتي تستفيد من الحجم التقريبي للقيمة للتمييز بين seconds وmilliseconds في الاستخدام اليومي، لكن المطور الأفضل يعرف الوحدة من توثيق الـAPI بدل تخمينها من عدد الخانات. وإذا وصلت القيمة داخل استجابة لا يمكن تحليلها أصلًا، فابدأ من دليل أخطاء JSON الشائعة قبل تفسير الـTimestamp نفسه.
JavaScript يستخدم المللي ثانية في Date
مواصفة ECMAScript تعرف time value كعدد يمثل لحظة بدقة المللي ثانية، مع Epoch عند منتصف الليل في بداية 1 يناير 1970 UTC. وتحدد أن الثانية الواحدة تساوي 1000 millisecond. [المصدر: ECMAScript]
إذا أعطيت JavaScript قيمة seconds على أنها milliseconds من دون ضربها ×1000، ستفسر رقمًا أصغر بألف مرة وتصل إلى تاريخ قريب من بداية 1970 بدل التاريخ المقصود.

المنطقة الزمنية لا تغيّر اللحظة نفسها
لماذا يظهر التاريخ صحيحًا لكن الساعة مختلفة؟
بعد حل مشكلة الوحدة تأتي المنطقة الزمنية. Timestamp يمثل لحظة، لكن عرض تلك اللحظة قد يكون UTC أو الوقت المحلي للمستخدم. اللحظة نفسها يمكن أن تظهر 12:00Z في UTC ووقتًا محليًا مختلفًا حسب offset والمنطقة الزمنية.
RFC 3339 صُمم لتقليل الالتباس في تمثيل timestamps على الإنترنت، ويستخدم علاقة واضحة مع UTC: الحرف Z يعني offset صفر، ويمكن كتابة offsets مثل +01:00 أو -08:00. [المصدر: RFC 3339]
UTC ووقت المتصفح في أداة تولاتي
محوّل Timestamp في صفحة أدوات المطورين يعرض نسخة محلية بحسب منطقة المتصفح، ونسخة ISO/UTC للمقارنة. هذه المقارنة مفيدة عندما ترى فرق ساعات بين الواجهة والخادم.
إذا كانت نسخة UTC صحيحة والوقت المحلي مختلفًا، فقد لا تكون هناك مشكلة في Timestamp أصلًا؛ قد يكون الاختلاف مجرد timezone display.
حالات تسبب اللبس
أكثر الأخطاء شيوعًا
التاريخ يقفز باتجاه 1970 لأن الرقم أصغر بألف مرة من المتوقع.
القيمة تصبح ضخمة جدًا وقد تخرج عن النطاق أو تنتج تاريخًا بعيدًا وغير منطقي.
تظهر إزاحة ساعات رغم أن اللحظة الأساسية صحيحة.
تفسيرها قد يعتمد على قواعد parser والسياق بدل أن تكون لحظة واضحة بين الأنظمة.
هل Timestamp يحتوي المنطقة الزمنية؟
القيمة العددية نفسها لا تحمل اسم مدينة أو “Africa/Casablanca”. إنها تحدد لحظة وفق نظام العد. عندما تحولها إلى وقت محلي تحتاج قواعد المنطقة الزمنية في النظام الذي يعرضها.
هذا فرق مهم عن نص RFC 3339 الذي يمكن أن يحتوي offset صريحًا. وحتى offset مثل +01:00 ليس اسم منطقة زمنية كاملة؛ هو الإزاحة في تلك اللحظة.
ماذا عن التوقيت الصيفي؟
قواعد التوقيت المحلي قد تتغير حسب التاريخ والقوانين المحلية. لذلك تخزين “الساعة 14:00” من دون منطقة أو offset مناسب قد يكون أكثر غموضًا من تخزين لحظة ثم تحويلها عند العرض.
RFC 3339 نفسه يشرح أن قواعد local time قد تكون معقدة وقابلة للتغيير، ويشجع على علاقات واضحة مع UTC في تبادل timestamps بين الأنظمة. [المصدر: RFC 3339]
Timestamp السالب ماذا يعني؟
في كثير من الأنظمة، القيم السالبة تستخدم لتمثيل أوقات قبل Epoch. لكن دعمها ونطاقها الفعلي يعتمد على اللغة والمنصة. لا تفترض أن كل API يقبل تاريخًا قبل 1970 لمجرد أن التمثيل النظري يسمح به.
كيف تشخص قيمة مجهولة؟
ابدأ بالسياق: اسم الحقل، توثيق API، اللغة التي أنتجته. إذا لم يتوفر شيء، جرّب فرضية seconds وmilliseconds وقارن التاريخ الناتج بمنطق البيانات. إذا أعطت إحدى الفرضيتين تاريخًا معقولًا والأخرى سنة غير منطقية، حصلت على إشارة قوية، لكن وثائق المصدر تبقى المرجع الأفضل.
التحويل والتمثيل النصي
Timestamp مقابل نص تاريخ قابل للقراءة
الأرقام مناسبة للحساب والترتيب والتخزين البرمجي، بينما صيغة مثل RFC 3339 أسهل للبشر والتشخيص وتستطيع إظهار offset. لا توجد صيغة “أفضل دائمًا”؛ المهم أن العقد بين الأنظمة يحدد الوحدة والمنطقة أو العلاقة بـUTC بوضوح.
تغيير المنطقة الزمنية لا يغيّر اللحظة نفسها
إذا كانت لديك قيمة Timestamp صحيحة ثم عرضتها في UTC وبعدها في توقيت محلي، لا يفترض أن تتغير اللحظة التي تمثلها؛ الذي يتغير هو الساعة والتاريخ المكتوبان للمستخدم بحسب offset وقواعد المنطقة. لهذا لا “تصحح” فرق الساعات بإضافة أو طرح ساعات من Timestamp الخام إذا كان أصل المشكلة مجرد طريقة عرض.
الممارسة الأفضل أن تحتفظ باللحظة بصيغة واضحة ومتفق عليها، ثم تطبق المنطقة الزمنية في طبقة العرض. تعديل القيمة نفسها يدويًا لتعويض timezone قد يؤدي إلى تطبيق الإزاحة مرتين عندما تصل البيانات إلى نظام آخر.
created_at_ms أو توثيق صريح بأن القيمة seconds تمنع أخطاء كان يمكن تجنبها بالكامل.مثال تصحيح سريع
واجهة ترسل رقمًا من 13 خانة، والخادم يتوقع seconds. الحل ليس تعديل المنطقة الزمنية؛ المشكلة تحدث قبلها. حوّل الوحدة بالقسمة على 1000 أو اتفق على milliseconds في الطرفين. بعد ذلك فقط افحص طريقة العرض المحلي.
وفي الاتجاه الآخر، إذا كان API يعيد seconds إلى JavaScript Date، اضرب في 1000 قبل إنشاء الكائن عندما تكون الواجهة المستخدمة تتوقع milliseconds.
حوّل القيمة في الاتجاهين
أداة Timestamp في تولاتي تحول الرقم إلى تاريخ محلي وUTC، وتحوّل التاريخ إلى قيمة زمنية، مع تمييز عملي بين قيم الثواني والمللي ثانية.
المصادر الرسمية المستخدمة
- The Open Group — POSIX Seconds Since the Epoch: تعريف الوقت بالثواني منذ Epoch وسلوك الأيام وleap seconds في POSIX.
- ECMAScript — Date Objects and Time Values: استخدام المللي ثانية وEpoch في JavaScript.
- IETF RFC 3339 — Date and Time on the Internet: تمثيل التاريخ والوقت وUTC offsets في بروتوكولات الإنترنت.
