Unix Timestamp: ما الفرق بين 10 أرقام و13 رقمًا ولماذا يختل الوقت؟

دليل عملي يشرح Unix Timestamp والفرق بين الثواني والمللي ثانية، ولماذا تظهر تواريخ 1970 أو فروق الساعات بسبب الوحدة والمنطقة الزمنية.

تحويل Unix Timestamp إلى تاريخ ووقت
الرقم قد يمثل اللحظة نفسها بوحدات مختلفة؛ الخطأ في الوحدة يرسل التاريخ عقودًا بعيدًا.

تنسخ قيمة مثل 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 نفسه.

إذا كانت وثائق API تقول إن الحقل بالمللي ثانية، صدّق الوثائق ولا تعد الخانات. التخمين مفيد عند فحص قيمة مجهولة، وليس بديلًا عن عقد واضح بين الأنظمة.

JavaScript يستخدم المللي ثانية في Date

مواصفة ECMAScript تعرف time value كعدد يمثل لحظة بدقة المللي ثانية، مع Epoch عند منتصف الليل في بداية 1 يناير 1970 UTC. وتحدد أن الثانية الواحدة تساوي 1000 millisecond. [المصدر: ECMAScript]

لذلك يظهر الخطأ الشهير

إذا أعطيت JavaScript قيمة seconds على أنها milliseconds من دون ضربها ×1000، ستفسر رقمًا أصغر بألف مرة وتصل إلى تاريخ قريب من بداية 1970 بدل التاريخ المقصود.

الفرق بين Timestamp بالثواني والمللي ثانية
الوحدة الأصغر تحتاج رقمًا أكبر لتمثيل اللحظة نفسها: milliseconds = seconds × 1000.

المنطقة الزمنية لا تغيّر اللحظة نفسها

لماذا يظهر التاريخ صحيحًا لكن الساعة مختلفة؟

بعد حل مشكلة الوحدة تأتي المنطقة الزمنية. Timestamp يمثل لحظة، لكن عرض تلك اللحظة قد يكون UTC أو الوقت المحلي للمستخدم. اللحظة نفسها يمكن أن تظهر 12:00Z في UTC ووقتًا محليًا مختلفًا حسب offset والمنطقة الزمنية.

RFC 3339 صُمم لتقليل الالتباس في تمثيل timestamps على الإنترنت، ويستخدم علاقة واضحة مع UTC: الحرف Z يعني offset صفر، ويمكن كتابة offsets مثل +01:00 أو -08:00. [المصدر: RFC 3339]

Timestamp ليس “توقيتًا محليًا”. هو تمثيل للحظة؛ التطبيق هو الذي يقرر كيف يعرضها للمستخدم وبأي منطقة زمنية.

UTC ووقت المتصفح في أداة تولاتي

محوّل Timestamp في صفحة أدوات المطورين يعرض نسخة محلية بحسب منطقة المتصفح، ونسخة ISO/UTC للمقارنة. هذه المقارنة مفيدة عندما ترى فرق ساعات بين الواجهة والخادم.

إذا كانت نسخة UTC صحيحة والوقت المحلي مختلفًا، فقد لا تكون هناك مشكلة في Timestamp أصلًا؛ قد يكون الاختلاف مجرد timezone display.

حالات تسبب اللبس

أكثر الأخطاء شيوعًا

seconds تُقرأ كـmilliseconds

التاريخ يقفز باتجاه 1970 لأن الرقم أصغر بألف مرة من المتوقع.

milliseconds تُقرأ كـseconds

القيمة تصبح ضخمة جدًا وقد تخرج عن النطاق أو تنتج تاريخًا بعيدًا وغير منطقي.

UTC يُعامل كأنه local time

تظهر إزاحة ساعات رغم أن اللحظة الأساسية صحيحة.

السلسلة بلا timezone واضح

تفسيرها قد يعتمد على قواعد 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 قد يؤدي إلى تطبيق الإزاحة مرتين عندما تصل البيانات إلى نظام آخر.

لا تسمِّ الحقل timestamp فقط إذا كانت الوحدة غير واضحة. أسماء مثل created_at_ms أو توثيق صريح بأن القيمة seconds تمنع أخطاء كان يمكن تجنبها بالكامل.

مثال تصحيح سريع

واجهة ترسل رقمًا من 13 خانة، والخادم يتوقع seconds. الحل ليس تعديل المنطقة الزمنية؛ المشكلة تحدث قبلها. حوّل الوحدة بالقسمة على 1000 أو اتفق على milliseconds في الطرفين. بعد ذلك فقط افحص طريقة العرض المحلي.

وفي الاتجاه الآخر، إذا كان API يعيد seconds إلى JavaScript Date، اضرب في 1000 قبل إنشاء الكائن عندما تكون الواجهة المستخدمة تتوقع milliseconds.

حوّل القيمة في الاتجاهين

أداة Timestamp في تولاتي تحول الرقم إلى تاريخ محلي وUTC، وتحوّل التاريخ إلى قيمة زمنية، مع تمييز عملي بين قيم الثواني والمللي ثانية.

فتح أدوات المطورين

ع م
عبد الكريم مرجانيكاتب موقع تولاتي — يراجع الأدلة التقنية بالرجوع إلى POSIX ومواصفات ECMAScript وIETF.

المصادر الرسمية المستخدمة

  1. The Open Group — POSIX Seconds Since the Epoch: تعريف الوقت بالثواني منذ Epoch وسلوك الأيام وleap seconds في POSIX.
  2. ECMAScript — Date Objects and Time Values: استخدام المللي ثانية وEpoch في JavaScript.
  3. IETF RFC 3339 — Date and Time on the Internet: تمثيل التاريخ والوقت وUTC offsets في بروتوكولات الإنترنت.