أرسل أحد مستخدمي أحد تطبيقات Laravel SaaS الخاصة بي بريدًا إلكترونيًا ذات مرة ليخبرنا أن تاريخ تجديد اشتراكه يبدو "؛ سخية بعض الشيء."؛ أخبرته صفحة الفواتير أن خطته ستتجدد في 25 أبريل من العام 57123.
استغرق العثور على الخطأ وقتًا طويلاً بشكل محرج لأن كل قطعة على حدة كانت صحيحة. تم إرسال الواجهة الأمامية لـ React Date.now()- الذي يعود مللي ثانية- وقد فعلت الواجهة الخلفية لـ PHP date('Y-m-d', $timestamp)الذي يتوقع ثواني. يغذي 1740470400000 في وظيفة توقع 1740470400 وستهبط ما يقرب من 55000 سنة في المستقبل. لا استثناء ولا تحذير ولا اختبار فاشل. مجرد عميل يسأل بأدب عما إذا كان اشتراكه قد استمر بالفعل حتى الموت الحراري للحضارة.
تبدو الطوابع الزمنية وكأنها الموضوع الأكثر مللاً في البرامج. هم '؛ هي في الواقع واحدة من مصانع الأخطاء الأكثر موثوقية لدينا: الثواني مقابل المللي ثانية، UTC مقابل المحلية، انتقالات التوقيت الصيفي، التمديد لعام 2038. ال محول الطابع الزمني يوجد في Toolz.dev لأنني سئمت من القيام بذلك new Date(x * 1000) في وحدة تحكم المتصفح أربعين مرة في اليوم. يغطي هذا الدليل ما أتحقق منه الآن، بالترتيب الذي أتحقق منه.
ليرة تركية؛DR: يقوم الطابع الزمني لنظام Unix بحساب الثواني منذ 1970-01-01T00:00:00 UTC. 10 أرقام = ثواني، 13 رقم = مللي ثانية- خلطها يضع تواريخك في وضع إيقاف لمدة 55000 سنة. قم بتخزين UTC، وقم بالتحويل للعرض فقط، واستخدم أسماء مناطق IANA مثل
Asia/Dhakaبدلا من الاختصارات. لصق أي طابع زمني في محول الطابع الزمني للحصول على نماذج ISO 8601 وRFC 2822 والنماذج المحلية وUTC - يتم تشغيلها من جانب العميل، لذا يتم إلغاء الطوابع الزمنية JWTs وسجلات الإنتاج لا تترك متصفحك أبدًا.
ما هو الطابع الزمني لنظام Unix بالضبط؟
الطابع الزمني لنظام Unix (وقت العصر، وقت POSIX) هو عدد الثواني المنقضية منذ ذلك الحين 1 يناير 1970، الساعة 00:00:00 بالتوقيت العالمي- "؛ عصر يونكس."؛ It'؛s عدد صحيح واحد، ليس له منطقة زمنية (it'؛s دائمًا UTC حسب التعريف)، ويفهمه كل نظام تشغيل ولغة وقاعدة بيانات بشكل فعال. هذه الخاصية الأخيرة هي سبب بقائها على قيد الحياة لمدة خمسة عقود: إنها التنسيق الذي لا يجادل فيه أحد.
لماذا 1970؟ لا يوجد سبب عميق - لقد كان تاريخًا تقريبيًا مناسبًا بالقرب من وقت بناء Unix في Bell Labs، وكان Unix المبكر يحسب الوقت في عدد صحيح 32 بت. لقد تحول الاختيار التعسفي إلى معيار عالمي، وهو يونكس للغاية.
بعض النقاط المرجعية التي تستحق التعرف عليها فور رؤيتها:
| الطابع الزمني | تاريخ التوقيت العالمي المنسق | لماذا أنت '؛د رؤيته |
|---|---|---|
0 |
01-01-1970 00:00:00 | العصر. وأيضا ما تحصل عليه من null/0 الأخطاء - التاريخ الذي يظهر على الشاشة في عام 1970 يعني دائمًا قيمة غير مهيأة، وليس السفر عبر الزمن |
946684800 |
2000-01-01 00:00:00 | Y2K |
1234567890 |
2009-02-13 23:31:30 | في الواقع، أقام المطورون حفلات لهذا الحفل |
1740470400 |
25-02-2025 08:00:00 | طابع زمني حديث عادي مكون من 10 أرقام |
2147483647 |
19-01-2038 03:14:07 | الحد الأقصى الموقع 32 بت - راجع Y2038 أدناه |
هذا الصف الرابع هو المثال المفضل لدي لسبب خفي: قائمة الكثير من الصفحات التعليمية 1740470400 as "؛ 25 فبراير 2025، الساعة 12:00:00."؛ إنه '؛s في الواقع 08:00 بالتوقيت العالمي- قام شخص ما بتحويله إلى منطقته الزمنية المحلية مرة واحدة وتم نسخ القيمة الخاطئة منذ ذلك الحين. التحقق من الطوابع الزمنية باستخدام أداة، وليس باستخدام منشور مدونة. بما في ذلك هذا واحد.
ثواني أم ميلي ثانية - كيف تقول؟
عد الأرقام. لأي تاريخ في العصر الحالي:
- 10 أرقام (
1740470400) - ثواني. اتفاقية يونكس، معظم واجهات برمجة التطبيقات، PHP'؛stime()بايثون '؛سtime.time()(كعائم)، Stripe'؛s API. - 13 رقما (
1740470400000) - مللي ثانية. جافا سكريبت '؛سDate.now()جافا'؛سSystem.currentTimeMillis()، تواريخ MongoDB.
هذا هو التمييز الدقيق الذي أنتج تاريخ التجديد الخاص بي للعام 57123، لذا سأوضح I'؛ أوضاع الفشل:
- يتم تفسير MS على أنها ثوانٍ → تواريخ ~ 55000 سنة في مستقبل
- يتم تفسير الثواني على أنها ms → التواريخ في يناير 1970 (كل شيء ينهار خلال ~ 3 أسابيع من العصر)
إذا رأيت التوقيع - تواريخ قديمة أو تواريخ مستقبلية سخيفة - فأنت تعرف الخطأ قبل قراءة سطر من التعليمات البرمجية. ال محول الطابع الزمني يكتشف عدد الأرقام ويصنف كلا التفسيرين، مما يؤدي إلى تسوية "؛ هل هذا s أو ms؟"؛ حجة في ثانيتين.
ما هي تنسيقات التاريخ التي تحتاج إلى معرفتها بالفعل؟
ثلاثة تغطي تقريبًا كل ما يلمسه المطور العامل.
ايزو 8601- المعيار الدولي، وما يجب عليك إصداره في واجهات برمجة التطبيقات والسجلات
2026-07-13T09:30:45Z UTC ("Z" = Zulu)
2026-07-13T15:30:45+06:00 with timezone offset
2026-07-13T09:30:45.123Z with milliseconds
الميزة القاتلة التي لم يذكرها أحد: سلاسل ISO 8601 فرز معجميا بالترتيب الزمني. sort في ملف السجل يعمل فقط. 02/25/2026-تنسيقات النمط يمكن '؛ تفعل ذلك - والأسوأ من ذلك، الولايات المتحدة MM/DD والأوروبية DD/MM لا يمكن تمييزها لمدة اثني عشر يومًا من كل شهر.
RFC 3339 (المواصفات) - ملف تعريف بروتوكول الإنترنت الخاص بمعيار ISO 8601. أكثر صرامة قليلاً؛ إذا كانت واجهة برمجة التطبيقات الخاصة بك تنبعث 2026-07-13T09:30:45Z أنت ترضي كليهما. هذا هو التنسيق الذي يجب توحيده.
RFC 2822 (Sun, 13 Jul 2026 09:30:45 +0000) - رؤوس البريد الإلكتروني وHTTP، وخلاصات RSS. تقرأه أكثر مما تكتبه.
تنسيقات قواعد البيانات هي أبناء عمومة قريبون: MySQL DATETIME يكون 2026-07-13 09:30:45 (ISO مع مساحة)، PostgreSQL timestamptz يعرض 2026-07-13 09:30:45+00.
كيف تتعامل اللغات التي أستخدمها مع الطوابع الزمنية؟
الثلاثة من مجموعتي الخاصة - والغرابة في كل منها كلفتني وقتًا شخصيًا.
جافا سكريبت (السيدة الأولى):
Math.floor(Date.now() / 1000) // current Unix seconds — Date.now() is ms!
new Date(1740470400 * 1000) // seconds → Date: multiply by 1000
date.toISOString() // "2025-02-25T08:00:00.000Z"
Date.parse('2026-07-13T09:30:45Z') / 1000 // ISO string → Unix seconds
كويرك: كل شيء هو ميلي ثانية، و new Date(1740470400) يعطيك بصمت 21 يناير 1970 بدلاً من فبراير 2025. لا يوجد خطأ. يعد عدم التماثل هذا هو خطأ الطابع الزمني الأكثر شيوعًا في تطوير الويب.
PHP (الثانية):
time(); // current Unix seconds
date('Y-m-d H:i:s', 1740470400); // "2025-02-25 08:00:00" (server TZ!)
strtotime('2026-07-13 09:30:45'); // string → timestamp
(new DateTime('@1740470400'))
->setTimezone(new DateTimeZone('Asia/Dhaka'))
->format(DateTime::ATOM); // "2025-02-25T14:00:00+06:00"
كويرك: date() التنسيقات في الخادم #39؛s المنطقة الزمنية الافتراضية، لذا يقوم نفس الرمز بطباعة تواريخ مختلفة على جهازك وفي مرحلة الإنتاج. أيضًا، new DateTime('@1740470400') يتجاهل أي منطقة زمنية تمررها إلى المنشئ - @ النموذج دائمًا UTC؛ يجب عليك الاتصال setTimezone() بعد. يضيف WordPress طبقته الخاصة: current_time('timestamp') إرجاع مزيف "؛ محلي وquot؛ إزاحة الطابع الزمني من وقت Unix الحقيقي، وهو أمر خطير تمامًا كما يبدو.
بايثون:
import time, datetime
int(time.time()) # current Unix seconds
datetime.datetime.fromtimestamp(1740470400,
tz=datetime.timezone.utc) # → aware datetime
dt.isoformat() # "2025-02-25T08:00:00+00:00"
كويرك: fromtimestamp() بدون tz= إرجاع وقت تاريخ ساذج بالتوقيت المحلي. أوقات التاريخ الساذجة هي خطأ وقت بايثون: فهي تقارن وتطرح بسعادة ضد بعضها البعض حتى اليوم الذي يعبر فيه أحدهم حدود التوقيت الصيفي. تمر دائما tz=؛ يستخدم zoneinfo (stdlib منذ 3.9) للمناطق المسماة.
كيف يجب أن تتعامل مع المناطق الزمنية دون أن تفقد عقلك؟
أربع قواعد، كلها تعلمت الطريقة المزعجة
- تخزين UTC. دائما. الطوابع الزمنية يونكس أو
timestamptzفي قاعدة البيانات. تصبح المنطقة الزمنية مصدر قلق للعرض فقط. - تحويل في طبقة العرض. يرى المستخدم في دكا
+06:00يرى المستخدم في برلين+02:00، قاعدة البيانات لا ترى أي منهما. - استخدم أسماء IANA، وليس الاختصارات.
Asia/Dhaka،America/New_York،Europe/Berlin. الاختصارات غامضة -CSTيعني التوقيت الرسمي للولايات المتحدة الوسطى أو الصين أو التوقيت الرسمي لكوبا اعتمادًا على من '؛s القراءة - والاختصارات don'؛t تشفر قواعد التوقيت الصيفي. أسماء IANA تفعل. - لا تقم أبدًا بلف منطق التوقيت الصيفي يدويًا. تختلف تواريخ التوقيت الصيفي حسب البلد، وتتغير حسب التشريعات، وبعض الأماكن (أريزونا وبنغلاديش واليابان) لا '؛ تراقب التوقيت الصيفي على الإطلاق. قاعدة بيانات IANA tz موجودة لأن هذا صعب حقًا؛ استخدم المكتبة التي تغلفها.
النتيجة الطبيعية للقاعدة 1: عندما يختلف نظامان حول وقت الحدث، قم بتحويل كلتا القيمتين إلى طوابع زمنية UTC Unix وقارن الأعداد الصحيحة. الحجج حول "؛ لكنه يقول 3 مساءً هنا"؛ تذوب على الفور.
ما هي مشكلة Y2038، وهل يجب أن تهتم؟
الحد الأقصى لعدد صحيح موقع 32 بت عند 2,147,483,647. كطابع زمني لنظام Unix، that'؛s 19 يناير 2038، الساعة 03:14:07 بالتوقيت العالمي. وبعد ثانية واحدة، تصبح القيمة سلبية - حتى 13 ديسمبر 1901.
يبدو بعيدا؛ إنه '؛t، لسببين. أولاً، '؛s بعد حوالي 11.5 عامًا وأنا أكتب هذا - داخل عمر الأنظمة المدمجة، ووحدات التحكم الصناعية، وتلك الخدمة القديمة التي لا يريد أحد لمسها. ثانيا، مستقبل ظهرت التواريخ على الحائط مبكرًا: فالنظام الذي يحسب جدول الرهن العقاري لمدة 15 عامًا أو انتهاء صلاحية الشهادة لمدة 20 عامًا يتجاوز عام 2038 اليوم. MySQL'؛s TIMESTAMP نوع العمود هو المصيدة الكلاسيكية - it'؛s 32 بت يحدها ويمكن '؛t يعود تاريخ المتجر إلى ما بعد 2038-01-19، بينما DATETIME في نفس قاعدة البيانات على ما يرام.
أنت '؛ آمنة على 64 بت time_t (أي نظام تشغيل حديث)، وجافا سكريبت (تعويم 64 مللي ثانية)، وبايثون (دقة تعسفية)، وPostgreSQL. أنت '؛ معرضون للخطر على الأنظمة المدمجة 32 بت، القديمة TIMESTAMP الأعمدة، ورمز C الذي تم ترميزه int32_t للوقت. الاختبار بسيط: ادفع 2147483648 (واحد بعد الحد) من خلال خط الأنابيب الخاص بك ومعرفة ما يخرج. ال محول الطابع الزمني سوف تولد لك بكل سرور قيم اختبار ما بعد عام 2038.
أين تظهر الطوابع الزمنية في التصحيح الحقيقي؟
انتهاء JWT. تحمل الرموز iat و exp المطالبات كثواني يونكس:
{ "sub": "user_8241", "iat": 1783915890, "exp": 1783919490 }
"؛ لماذا قام هذا المستخدم بتسجيل الخروج؟"؛ يتم الرد عليه عن طريق التحويل exp. فك تشفير الرمز المميز في JWT فك التشفير وقم بتحويل المطالبة - كلاهما يتم تشغيلهما من جانب العميل، وهو أمر مهم لأن الرمز المميز الملصق هو بيانات اعتماد مباشرة ( دليل خصوصية البيانات يغطي سبب رفضي وضع الرموز المميزة في الأدوات من جانب الخادم).
ارتباط السجل. حادثة واحدة، ثلاث خدمات، ثلاثة تنسيقات: سجلات nginx [13/Jul/2026:09:30:45 +0000]، يسجل التطبيق ISO 8601، ويقوم عامل قائمة الانتظار بتسجيل الثواني الأولية للعصر. تحويل كل شيء إلى تنسيق واحد هو الخطوة صفر من إنشاء جدول زمني.
تكامل API. يرسل الشريط "created": 1740470400 (ثواني). ترسل واجهة برمجة التطبيقات المبنية على JavaScript 1740470400000 (مللي ثانية). ترسل واجهات برمجة تطبيقات Google سلاسل RFC 3339. إذا كنت تستهلك الثلاثة جميعًا، فإن التحويل يكون '؛ وأحيانًا - it'؛s ثابتًا. تنسيق الحمولات في تنسيق JSON وتحويل الحقول المثيرة للاهتمام.
استعلامات النطاق الزمني. WHERE created_at >= 1752364800 AND created_at < 1752451200- هل هذا هو اليوم المناسب؟ تحويل كلا الحدود والتحقق، في التوقيت العالمي المنسق، قبل تشغيل الحذف. ذات صلة: ال حاسبة فرق التاريخ ل "؛ كم عدد الأيام بين هذين؟"؛، ال محول المنطقة الزمنية للرياضيات في وقت الاجتماع، و محلل كرون ل "؛ متى يتم تشغيل هذا الجدول فعليًا؟"؛.
الأسئلة الشائعة
ما هو الطابع الزمني لـ UNIX؟
عدد الثواني المنقضية منذ 1 يناير 1970، الساعة 00:00:00 بالتوقيت العالمي (عصر يونكس)، مخزنة كعدد صحيح واحد. It'؛s مستقلة عن المنطقة الزمنية بحكم التعريف - نفس اللحظة هي نفس الرقم في كل مكان على الأرض - ولهذا السبب '؛s تنسيق التبادل القياسي عبر أنظمة التشغيل واللغات وقواعد البيانات.
لماذا تحتوي بعض الطوابع الزمنية على 10 أرقام والبعض الآخر 13؟
10 أرقام هي الثواني (اتفاقية Unix القياسية، PHP، معظم واجهات برمجة التطبيقات)؛ 13 رقمًا هي ميلي ثانية (JavaScript'؛s Date.now()، جافا). اقسم على 1000 للانتقال من مللي ثانية إلى ثانية. الخلط بين تاريخ النوبتين إما ~ 55000 سنة في المستقبل أو العودة إلى يناير 1970.
هل يمكن أن تمثل الطوابع الزمنية لنظام Unix تواريخ ما قبل عام 1970؟
نعم - يتم احتساب القيم السالبة بشكل عكسي من تلك الحقبة. -86400 هو 31 ديسمبر 1969. يعود الطابع الزمني الموقع 32 بت إلى 13 ديسمبر 1901. ومع ذلك، ترفض بعض الأنظمة وواجهات برمجة التطبيقات الطوابع الزمنية السلبية، لذا قم باختبارها قبل الاعتماد عليها.
ما هي مشكلة Y2038؟
تجاوز الطوابع الزمنية الموقعة 32 بت عند 2،147،483،647 - 19 يناير 2038، الساعة 03:14:07 بالتوقيت العالمي المنسق - حتى ديسمبر 1901. لم تتأثر أنظمة 64 بت الحديثة، ولكن الأجهزة المدمجة 32 بت، ورمز C القديم، وMySQL TIMESTAMP الأعمدة مكشوفة. واجهت أنظمة حساب تواريخ المستقبل البعيد (الرهون العقارية والشهادات) الخطأ قبل سنوات من وصول عام 2038.
لماذا يظهر تاريخي يناير 1970؟
وصل الطابع الزمني صفر أو قريب من الصفر إلى رمز التنسيق الخاص بك - عادةً ما تكون قيمة غير مهيأة، أو تحليل فاشل يعود إلى 0، أو تمر الثواني حيث كان من المتوقع أن يكون المللي ثانية. تاريخ 1970 الذي يظهر على الشاشة لا يمثل أبدًا نقطة بيانات؛ it'؛s فارغة ترتدي زيًا.
هل يجب علي تخزين الطوابع الزمنية أو سلاسل وقت التاريخ في قاعدة البيانات الخاصة بي؟
قم بتخزين UTC في كلتا الحالتين - النوع أقل أهمية من نظام المنطقة الزمنية. الأعداد الصحيحة لنظام Unix مدمجة، وفرزها بشكل تافه، وتفادي التحليل تمامًا؛ timestamptz/DATETIME يمكن قراءة الأعمدة بواسطة الإنسان في نتائج الاستعلام وتدعم حساب التاريخ في SQL. ما لا يجب عليك فعله هو تخزين الأوقات المحلية دون إزاحات - فقدان البيانات '؛s الذي تكتشفه فقط عند انتقال التوقيت الصيفي التالي.
هل يتأثر العصر بالثواني الكبيسة؟
عمليا لا. يتظاهر وقت يونكس بالثواني الكبيسة don'؛ موجود - كل يوم هو بالضبط 86400 ثانية، وعادةً ما تقوم الأنظمة بتلطيخ الساعة أو تحريكها عند حدوث ثانية كبيسة. بالنسبة لرمز التطبيق، هذه ليست مشكلة؛ إنه مهم فقط في سياقات التوقيت العلمية، حيث يتم استخدام وقت TAI أو GPS بدلاً من ذلك.
هل من الآمن لصق الطوابع الزمنية لسجل الإنتاج في محول عبر الإنترنت؟
يكشف الطابع الزمني الأولي وحده عن القليل، ولكن الطوابع الزمنية تنتقل عادةً مع السياق - معرفات المستخدم، ومطالبات الرمز المميز، وخطوط السجل. ال محول الطابع الزمني يقوم Toolz.dev بالتحويل بالكامل في متصفحك دون إرسال أي بيانات، لذا فإن لصق القيم مباشرة من سجلات الإنتاج أو JWTs لا يكشف '؛t أي شيء.
كيف يمكنني تحويل الطابع الزمني لنظام Unix إلى تاريخ قابل للقراءة؟
الصق الرقم في محول واقرأ UTC والنتائج المحلية، أو قم بذلك في الكود new Date(ts * 1000).toISOString() في جافا سكريبت، datetime.fromtimestamp(ts, tz=timezone.utc) في بايثون، date -u -d @ts على لينكس. الشيء الوحيد الذي يجب عليك فعله أولاً هو ما إذا كانت قيمتك بالثواني أو المللي ثانية - كل شيء آخر يتبع ذلك.
كيف يمكنني الحصول على الطابع الزمني الحالي لنظام Unix؟
date +%s في قذيفة، Math.floor(Date.now() / 1000) في جافا سكريبت، int(time.time()) في بايثون، SELECT EXTRACT(EPOCH FROM NOW()) في PostgreSQL. لاحظ أن JavaScript هو الخيار الغريب: Date.now() إرجاع المللي ثانية، وبالتالي فإن القسمة ليست اختيارية.



