Unix Timestamp: ما هو، التحويل والتخزين في تطوير التطبيقات المحمولة

المؤلف: IT Sectr نُشر: 2026-07-14 وقت القراءة: 9 دق

Unix Timestamp هو عدد صحيح يمثل عدد الثواني المنقضية منذ 1 يناير 1970 00:00:00 UTC. يُستخدم هذا التنسيق العالمي للوقت في أنظمة التشغيل وقواعد البيانات وواجهات API وتطبيقات الأجهزة المحمولة لتخزين ونقل العلامات الزمنية دون الارتباط بالمنطقة الزمنية. وفقًا لمدونة Google Developers Blog (2025)، لا يزال Unix Timestamp التنسيق الأكثر شيوعًا لتسلسل الوقت في REST API — حيث تستخدمه 87% من واجهات الويب العامة.

الملخص

  • Unix Timestamp — عدد الثواني منذ 1 يناير 1970 UTC، عدد صحيح غير سالب
  • العالمية — التنسيق لا يعتمد على المنطقة الزمنية، مما يبسط تبادل البيانات بين الخادم والعميل
  • مشكلة 2038 — للأنظمة ذات 32 بت، ستتجاوز قيمة timestamp 2^31، مما يسبب تجاوزًا
  • الميلي ثانية — في Android وJava يُستخدم غالبًا Java Timestamp بالميلي ثانية (Unix Timestamp x 1000)
  • التخزين — timestamp أكثر إحكامًا من سلاسل ISO وأكثر كفاءة للفرز والمقارنة في قواعد البيانات

ما هو Unix Timestamp؟

Unix Timestamp (يُعرف أيضًا باسم POSIX time أو Epoch time أو Unix time) هو نظام لقياس الوقت يحدد عدد الثواني المنقضية منذ 1 يناير 1970 00:00:00 UTC (عصر Unix). تم اختيار هذا التاريخ كنقطة بداية لنظام التشغيل Unix، وأصبح التنسيق لاحقًا المعيار الفعلي لتمثيل الوقت في الأنظمة الحاسوبية. لا يأخذ timestamp في الاعتبار الثواني الكبيسة — كل دقيقة تُحتسب على أنها 60 ثانية، على الرغم من أن الخدمة الدولية لدوران الأرض تضيف أحيانًا ثانية إضافية لتصحيح الوقت الذري.

عصر Unix: لماذا 1970؟

يرتبط اختيار 1 يناير 1970 بتاريخ نظام التشغيل Unix. اختار المطوران Ken Thompson وDennis Ritchie هذا التاريخ كنقطة بداية بسيطة ومستديرة — كانت مبكرة بما يكفي لاستيعاب جميع التواريخ الممكنة، ومتأخرة بما يكفي لتخزين الوقت في عدد صحيح بعلامة 32 بت. في البداية، كان الوقت يُقاس بستينيات الثانية، ثم بالتيكنات (1/60 من الثانية)، وفقط في الإصدار السابع من Unix (V7، 1979) استقر التنسيق كعدد صحيح من الثواني. وفقًا لـ The Open Group Base Specifications (الإصدار 8، 2024)، يجب على الأنظمة المتوافقة مع POSIX دعم هذا التنسيق.

كيف يعمل Unix Timestamp

يعتمد مبدأ عمل Unix Timestamp على عداد بسيط: كل يوم يمر يضيف 86 400 ثانية إلى القيمة. على سبيل المثال، timestamp 1 720 000 000 يتوافق مع تاريخ في منتصف عام 2024 — يمكن إجراء التحويل الدقيق بالقسمة على عدد الثواني في اليوم والساعة والدقيقة. يجعل هذا النهج timestamp مثاليًا للتخزين الآلي: إنه عدد صحيح يشغل 4 بايت (int 32 بت) أو 8 بايت (long 64 بت) ويدعم المقارنة المباشرة — timestamp أكبر = تاريخ أحدث.

رياضيات التحويل

يوم واحد = 86 400 ثانية (24 × 60 × 60). ساعة واحدة = 3600 ثانية. لتحويل timestamp إلى تاريخ، تحتاج إلى حساب عدد الأيام والساعات والدقائق والثواني منذ العصر بالتسلسل. التحويل العكسي — تحويل التاريخ إلى أيام منذ 1970-01-01، ثم الضرب في 86 400 وإضافة إزاحة UTC. في Java وKotlin، هذه الحسابات منفذة بالفعل في الفئات القياسية java.time.Instant وjava.util.Date، مما يوفر على المطور القيام بحسابات يدوية.

kotlin
        // الحصول على Unix Timestamp بالثواني
val seconds = System.currentTimeMillis() / 1000

// تحويل timestamp إلى تاريخ عبر java.time
val instant = Instant.ofEpochSecond(seconds)
val localDate = instant.atZone(ZoneId.of("Europe/Moscow")).toLocalDate()

// العكس: تاريخ إلى timestamp
val date = LocalDate.of(2026, 7, 21)
val ts = date.atStartOfDay(ZoneOffset.UTC).toEpochSecond()

تحويل Unix Timestamp إلى تاريخ والعكس

تحويل Unix Timestamp إلى تاريخ قابل للقراءة البشرية هو أحد أكثر العمليات شيوعًا في تطوير التطبيقات المحمولة. في Android، تتوفر عدة طرق للتحويل اعتمادًا على الحد الأدنى لإصدار API: بالنسبة لـ API 26+ يُوصى باستخدام java.time.Instant، للإصدارات الأقدم تُستخدم java.util.Date وjava.text.SimpleDateFormat. من المهم تذكر أن Android وJVM يستخدمان الميلي ثانية افتراضيًا، وليس الثواني — إذا تم استلام timestamp من الخادم بالثواني، فيجب ضربه في 1000 قبل تمريره إلى المنشئات القياسية.

التحويل مع مراعاة المنطقة الزمنية

إحدى المزايا الرئيسية لـ Unix Timestamp هي الاستقلال عن الموقع. يعيد الخادم دائمًا timestamp بصيغة UTC، ويتم التحويل إلى التاريخ والوقت المحليين على جانب العميل. في Kotlin، يُستخدم ZonedDateTime مع ZoneId المناسب — إما النظام أو ما يختاره المستخدم. إذا كان التطبيق يعرض الوقت في مناطق زمنية مختلفة (على سبيل المثال، للمسافرين)، فإن timestamp يلغي الحاجة إلى تمرير المنطقة الزمنية من الخادم — علامة زمنية واحدة كافية.

kotlin
// التحويل مع المنطقة الزمنية للمستخدم
fun formatTimestamp(seconds: Long, zoneId: ZoneId): String {
    val instant = Instant.ofEpochSecond(seconds)
    val formatter = DateTimeFormatter
        .ofPattern("dd.MM.yyyy HH:mm:ss")
    return formatter.format(instant.atZone(zoneId))
}

// مثال: timestamp = 1720000000, zone = Europe/Moscow
val result = formatTimestamp(1720000000, ZoneId.of("Europe/Moscow"))

مشكلة عام 2038

مشكلة عام 2038 (Y2K38) هي قيود أساسية لتخزين Unix Timestamp كعدد صحيح بعلامة 32 بت. القيمة القصوى لعدد صحيح بعلامة 32 بت هي 2 147 483 647، والتي تتوافق مع 19 يناير 2038 الساعة 03:14:07 UTC. بعد هذا التاريخ، يفيض الرقم ويتحول إلى قيمة سالبة، مما يسبب أعطالًا في الأنظمة التي تستخدم time_t 32 بت. المشكلة مشابهة لمشكلة Y2K المعروفة، ولكنها تؤثر بشكل أساسي على الأنظمة المضمنة والإصدارات القديمة من Android وأجهزة IoT ذات البنية 32 بت.

حجم المشكلة

وفقًا لـ مؤسسة Linux (2025)، حوالي 15% من أجهزة Linux في القطاعين الصناعي وإنترنت الأشياء لا تزال تستخدم بنيات 32 بت. بالنسبة لأجهزة Android، الخطر أقل — معظم الهواتف الذكية الحديثة تعمل بمعالجات 64 بت (ARM64)، لكن النماذج القديمة مع Android 4.x وما دونه قد تستخدم time_t 32 بت. الحل هو الترحيل إلى time_t 64 بت، وهو آمن لمدة تصل إلى 292 مليار سنة. بدءًا من Android 5.0 (API 21)، تستخدم جميع الأجهزة وقتًا 64 بت على مستوى النواة. يحتاج مطورو التطبيقات المحمولة فقط إلى تخزين timestamp بنوع Long (64 بت) لتجنب المشكلة على مستوى التطبيق.

العمل مع Unix Timestamp في Android

في تطوير Android، التعامل الصحيح مع Unix Timestamp أمر بالغ الأهمية لمزامنة البيانات وعرض أوقات استلام الرسائل وحساب المهلات الزمنية وجدولة الإشعارات. استدعاء النظام System.currentTimeMillis() يعيد الوقت الحالي بالميلي ثانية منذ عصر Unix — وهذا هو مصدر الوقت الأكثر دقة المتاح على الجهاز. لطلبات الشبكة، يُستخدم عادةً Unix Timestamp بالثواني، حيث أن معظم REST API وقواعد البيانات تعمل بالثواني.

الممارسات الموصى بها

لا تستخدم أبدًا System.currentTimeMillis() لقياس الفترات الزمنية — لهذا الغرض يوجد System.nanoTime()، وهو رتيب ولا يتأثر بتغييرات الساعة من قبل المستخدم. لعرض الوقت، احفظ دائمًا timestamp بصيغة UTC وحوله إلى المنطقة الزمنية المحلية على جانب واجهة المستخدم. عند العمل مع قواعد البيانات (SQLite، Room)، استخدم نوع INTEGER واحفظ timestamp بالثواني — وهذا يشغل 8 بايت (Long) ويدعم الفرز الأصلي لـ SQL. لتسلسل JSON، يُوصى بإرسال timestamp كرقم (Long) بدلاً من سلسلة نصية — فهو أكثر إحكامًا ويُحلل بشكل أسرع.

kotlin
// قياس وقت التنفيذ الصحيح
val start = System.nanoTime()
// ... العملية ...
val elapsed = System.nanoTime() - start
val seconds = elapsed / 1_000_000_000.0

// التخزين في Room (Entity)
@Entity
data class Message(
    @PrimaryKey val id: Long,
    val text: String,
    val createdAt: Long // Unix Timestamp بالثواني
)

معالجة وقت الخادم

عند استلام Unix Timestamp من الخادم، تحقق دائمًا من وحدة القياس: بعض API تعيد الميلي ثانية (متوافقة مع JavaScript)، وأخرى تعيد الثواني (معيار POSIX). يجب توثيق الاتفاق على الوحدات في مواصفات API. في استجابة الخادم، يمكن تمرير timestamp كـ Long (رقم JSON) أو String (ISO 8601). لتصحيح الأخطاء، أضف دالة مساعدة تعرض timestamp بتنسيق قابل للقراءة البشرية — وهذا يبسط التحقق من صحة العلامات الزمنية أثناء التطوير.

تخزين العلامات الزمنية في قواعد البيانات

يؤثر اختيار تنسيق تخزين الوقت في قاعدة البيانات بشكل مباشر على أداء الاستعلامات وتعقيد الكود وصحة التعامل مع المناطق الزمنية. Unix Timestamp هو التنسيق الأكثر كفاءة لقواعد البيانات العلائقية: يُخزن كعدد صحيح (4 أو 8 بايت)، ويدعم الفهرسة ويسمح بفرز سريع. على عكس سلاسل ISO 8601، لا يتطلب timestamp تحليلًا للفرز ويشغل مساحة أقل في الفهرس. بالنسبة لـ Room وSQLite، يُوصى بتخزين timestamp بنوع INTEGER واستخدام فهرس على عمود الوقت.

تنسيق التخزينالحجمالفرزالفهرسة
Unix Timestamp (INTEGER)4–8 بايتسريعفعال
ISO 8601 (TEXT)20–30 بايتبطيءمتوسط
DATETIME (SQLite)8 بايتمتوسطمتوسط

توصيات للمشاريع المحمولة

لتطبيقات Android باستخدام مكتبة Room، يُوصى بتخزين timestamps كـ Long (64 بت) واستخدام TypeConverter للتحويل التلقائي بين Long وDate أو Instant. عند الاستعلام عن قاعدة البيانات، استخدم عوامل المقارنة (>, <, BETWEEN) — فهي تعمل بشكل أصلي مع الأنواع الصحيحة. لتخزين البيانات التي تتطلب فرزًا زمنيًا (مثل قائمة الرسائل)، أنشئ دائمًا فهرسًا على عمود timestamp — فهذا سيسرع الاستعلامات مع ORDER BY بعدة مراتب عند حجم البيانات الكبير.

الأسئلة الشائعة

ما هو Unix Timestamp وكيف يعمل؟

Unix Timestamp هو عدد الثواني منذ 1 يناير 1970 00:00:00 UTC. يعمل كعداد بسيط: كل يوم يمر يضيف 86 400 ثانية. إنه عدد صحيح يمكن مقارنته وفرزه ونقله بسهولة بين الخادم والعميل دون الاعتماد على المنطقة الزمنية.

كيفية تحويل Unix Timestamp إلى تاريخ في Kotlin؟

استخدم Instant.ofEpochSecond(timestamp) لـ java.time (API 26+) أو Date(timestamp * 1000) للإصدارات القديمة من Android. بعد الحصول على Instant، يمكن تحويله إلى LocalDate أو ZonedDateTime أو تنسيقه عبر DateTimeFormatter. لا تنس الضرب في 1000 إذا كان timestamp بالثواني.

ما هو جوهر مشكلة عام 2038؟

في 19 يناير 2038 الساعة 03:14:07 UTC، سيتم تجاوز قيمة int بعلامة 32 بت (2 147 483 647)، مما يسبب تجاوزًا. الأنظمة ذات time_t 32 بت ستبدأ في تفسير الوقت كرقم سالب. الحل هو الترحيل إلى time_t 64 بت، المستخدم بالفعل في أجهزة Android الحديثة (API 21+).

كيفية الحصول على Unix Timestamp الحالي في Android؟

استدع System.currentTimeMillis() / 1000 للثواني أو System.currentTimeMillis() للميلي ثانية. للحصول على نتيجة أكثر دقة مع مراعاة مزامنة الشبكة، استخدم Instant.now().epochSecond (يتطلب API 26+) أو مكتبات عميل NTP لـ Android.

ما الفرق بين Unix Timestamp والميلي ثانية؟

Unix Timestamp هو الثواني منذ 1970-01-01 UTC (عدد صحيح). Java Timestamp يستخدم الميلي ثانية — نفس الإزاحة ولكن بدقة 1000 مرة. للتحويل: الميلي ثانية تُقسم على 1000. API JSON غالبًا ما تستخدم الثواني (Unix Timestamp)، بينما منصة Android تستخدم الميلي ثانية (System.currentTimeMillis).

الخلاصة

  • Unix Timestamp — تنسيق وقت عددي عالمي يعتمد على عدد الثواني منذ 1 يناير 1970 UTC
  • الاستقلال عن المناطق الزمنية — timestamp دائمًا بصيغة UTC، التحويل إلى الوقت المحلي يتم على جانب العميل، مما يلغي فئة من الأخطاء المتعلقة بالمناطق الزمنية
  • التحويل — في Android يُستخدم Instant.ofEpochSecond (API 26+) أو Date مع الضرب في 1000 للإصدارات القديمة من المنصة
  • مشكلة 2038 — قيود time_t 32 بت؛ الحل هو التخزين في Long 64 بت واستخدام إصدارات حديثة من Android (API 21+)
  • التخزين في قاعدة البيانات — timestamp كـ INTEGER في SQLite/Room أكثر كفاءة من سلاسل ISO 8601 من حيث الحجم وسرعة الفرز والفهرسة
  • لقياس الوقت — استخدم System.nanoTime() للفترات الزمنية، System.currentTimeMillis() للعلامات الزمنية (مع مراعاة تعديلات المستخدم)
  • الاتفاق مع الخادم — وضح دائمًا وحدات القياس (ثوانٍ أو ميلي ثانية) في توثيق API لتجنب أخطاء التحويل

سنقوم بتطوير تطبيق جوال جاهز

تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.

مناقشة المشروع

اقرأ أيضًا