Date: ما هو، نوع الوقت و TimeInterval في Foundation

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

Date هي بنية من Foundation تمثل لحظة زمنية محددة بغض النظر عن التقويم والمنطقة الزمنية. يخزن النوع عدد الثواني المنقضية منذ تاريخ المرجع 1 يناير 2001، ويوفر عمليات أساسية للمقارنة وحساب الفترات الزمنية. وفقًا لتوثيق Apple Developer (2025)، يتم استخدام Date في جميع أطر Apple: من UIKit و SwiftUI إلى CloudKit و Core Data. فهم كيفية عمل Date ضروري لأي مطور iOS، لأنه من المستحيل إدارة الوقت في التطبيق بدونه.

الخلاصة

  • Date — بنية Foundation تخزن لحظة زمنية مطلقة كعدد من الثواني من تاريخ المرجع.
  • TimeInterval — نوع Double لتمثيل الفاصل الزمني بين لحظتين زمنيتين بالثواني.
  • Date() — مُهيئ ينشئ كائنًا باللحظة الزمنية الحالية وقت الاستدعاء.
  • مقارنة التواريخ تتم عبر عوامل المقارنة أو طرق compare، earlierDate، laterDate.
  • DateFormatter — مكون إلزامي لعرض التواريخ للمستخدم بتنسيق قابل للقراءة.

ما هو Date في Foundation؟

Date هو نوع قيمة من إطار Foundation يلتقط لحظة زمنية مطلقة واحدة. على عكس تمثيلات التقويم (سنة، شهر، يوم)، لا يعتمد Date على المنطقة الزمنية أو نظام التقويم — إنها قيمة طابع زمني رقمية بحتة.

التمثيل الداخلي لـ Date هو TimeInterval (اسم مستعار لـ Double)، يخزن عدد الثواني نسبة إلى تاريخ المرجع — 1 يناير 2001، 00:00:00 UTC. اختارت Apple هذا التاريخ بدلاً من حقبة Unix (1970) للتوافق مع أنظمة NeXTSTEP القديمة، التي بنيت عليها iOS و macOS.

يستخدم Date كنوع الوقت القياسي في جميع واجهات برمجة تطبيقات Apple: UIDatePicker، DatePicker، UserDefaults، Codable، Core Data، CloudKit. بدون Date، من المستحيل العمل مع الجداول الزمنية والمؤقتات وأحداث التقويم وتسلسل البيانات وأي عمليات متعلقة بالوقت.

Date مقابل أنواع الوقت الأخرى

Date يختلف عن أنواع التقويم في أنه يمثل طابعًا زمنيًا ماديًا وليس قيمة قابلة للقراءة البشرية. نفس Date يمكن أن يتوافق مع تواريخ تقويم مختلفة في مناطق زمنية مختلفة. لاستخراج المكونات (سنة، شهر، يوم)، يتم تحويل Date عبر Calendar و DateComponents.

Date يختلف أيضًا عن DispatchTime، الذي يستخدم لإرسال المهام في Grand Central Dispatch. DispatchTime نسبي لوقت بدء تشغيل النظام، بينما Date هو طابع زمني مطلق يمكن حفظه ونقله واستعادته.

إنشاء Date في Swift

Date() هي أبسط طريقة لإنشاء كائن باللحظة الزمنية الحالية. المُهيئ بدون معلمات يعيد الوقت الدقيق للاستدعاء. لإنشاء تاريخ في الماضي أو المستقبل، استخدم TimeInterval وطريقة addingTimeInterval، أو التهيئة من Date موجود.

لإنشاء تاريخ عشوائي من المكونات، استخدم الزوج Calendar و DateComponents. يحول Calendar المكونات القابلة للقراءة البشرية (سنة، شهر، يوم، ساعة، دقيقة) إلى Date. يمكنك أيضًا تهيئة Date عبر ISO8601DateFormatter من سلسلة ISO 8601، أو عبر DateFormatter من تمثيل سلسلة عشوائي.

Date.distantPast و Date.distantFuture هما خاصيتان ثابتتان تمثلان لحظات بعيدة بلا حدود في الماضي والمستقبل. يتم استخدامهما كقيم حدية لتصفية وترتيب التواريخ في الخوارزميات.

swift
import Foundation

// إنشاء Date مع الوقت الحالي
let now = Date()
print("Current time: \(now)")

// تاريخ بعد ساعة واحدة (3600 ثانية)
let inOneHour = now.addingTimeInterval(3600)

// تاريخ من المكونات
var components = DateComponents()
components.year = 2025
components.month = 12
components.day = 25
let christmas = Calendar.current.date(from: components)!

يوضح المثال ثلاث طرق لإنشاء Date: الوقت الحالي، إضافة فاصل زمني، والإنشاء عبر DateComponents.جميع الطرق الثلاث تعيد قيمة من نوع Date بدقة ميلي ثانية. يستخدم Calendar.current تقويم نظام المستخدم — على أجهزة Apple، هذا عادة ما يكون التقويم الميلادي.

TimeInterval ومقارنة التواريخ

TimeInterval هو اسم مستعار لـ Double يمثل عدد الثواني بين لحظتين زمنيتين. تصل دقة TimeInterval إلى أجزاء من الميلي ثانية، وهو كافٍ لمعظم المهام العملية. يشير TimeInterval السالب إلى الماضي بالنسبة لنقطة المرجع.

يدعم Date جميع عوامل المقارنة القياسية: ==، <، >، <=، >=. يقوم Swift تلقائيًا بمقارنة قيم TimeInterval الداخلية. طريقة compare تعيد ComparisonResult مع الخيارات .orderedSame، .orderedAscending، .orderedDescending لمقارنة أكثر وضوحًا.

Date.distance(to:) هي طريقة تعيد TimeInterval إلى التاريخ المحدد. إذا كان التاريخ المستهدف في الماضي، تكون النتيجة سالبة. advanced(by:) تنشئ تاريخًا جديدًا بإضافة TimeInterval المحدد إلى التاريخ الحالي. تنفذ هذه الطرق بروتوكول Strideable، مما يسمح باستخدام Date في Range و ClosedRange.

swift
let start = Date()
let end = start.addingTimeInterval(86400)

// المقارنة باستخدام العوامل
if start < end {
    print("start is earlier")
}

// TimeInterval بين تاريخين
let interval: TimeInterval = end.timeIntervalSince(start)
print("Seconds: \(Int(interval / 60)) minutes")

// استخدام Date في نطاق
let range = start...end
let mid = start.addingTimeInterval(43200)
if range.contains(mid) {
    print("mid is between start and end")
}

TimeInterval بقيمة 86400 يتوافق مع يوم واحد. للفترات الأكثر تعقيدًا — أسابيع، أشهر، سنوات — استخدم Calendar و DateComponents، لأن هذه الوحدات لها طول متغير (سنوات كبيسة، التوقيت الصيفي). TimeInterval قابل للتطبيق فقط للفترات الثابتة بالثواني.

Calendar و DateComponents

Calendar هو الجسر بين Date والمكونات القابلة للقراءة البشرية. يحول Calendar Date إلى DateComponents (سنة، شهر، يوم، ساعة، دقيقة، ثانية) مع مراعاة المنطقة الزمنية والإعدادات المحلية. بدون Calendar، من المستحيل استخراج السنة أو الشهر من Date — Date لا يحتوي على هذه المعلومات بسبب طبيعته المطلقة.

طريقة Calendar.component تستخرج مكونًا واحدًا من Date: سنة، شهر، يوم، ساعة، دقيقة، ثانية، يوم الأسبوع، ربع السنة. طريقة Calendar.dateComponents تستخرج مجموعة من المكونات في استدعاء واحد — وهذا أكثر كفاءة من استدعاء component لكل حقل على حدة.

Calendar.isDateInToday، isDateInTomorrow، isDateInYesterday هي طرق ملائمة للتحقق من التواريخ النسبية. Calendar.dateInterval يعيد بداية ونهاية الفترة المحددة (يوم، أسبوع، شهر، سنة). Calendar.compare يقارن التواريخ بدقة تصل إلى المكون المحدد — على سبيل المثال، السنة دون اعتبار الشهر واليوم.

swift
let calendar = Calendar.current

// استخراج المكونات
let year = calendar.component(.year, from: Date())
let month = calendar.component(.month, from: Date())

// التحقق من التاريخ النسبي
if calendar.isDateInToday(someDate) {
    print("Today!")
}

// بداية ونهاية اليوم
let dayInterval = calendar.dateInterval(of: .day, for: Date())!
print("Day start: \(dayInterval.start)")
print("Day end: \(dayInterval.end)")

Calendar.current يستخدم إعدادات نظام المستخدم — التقويم والمنطقة الزمنية والإعدادات المحلية. للاختبار أو الحسابات المحددة، يمكنك إنشاء Calendar بمعلمات محددة عبر Calendar(identifier: .gregorian) وتعيين المنطقة الزمنية المطلوبة عبر الخاصية timeZone.

DateFormatter وعرض التاريخ

DateFormatter هو مكون إلزامي إذا كان Date بحاجة إلى العرض للمستخدم. يحول DateFormatter Date إلى سلسلة وفقًا للتنسيق والإعدادات المحلية المحددة. تحويل Date مباشرة إلى سلسلة عبر String(describing:) يعيد تمثيلًا تقنيًا مع تاريخ المرجع و TimeInterval — وهو غير مخصص للمستخدمين.

النهج الأساسي هو استخدام الأنماط المحددة مسبقًا dateStyle و timeStyle. يدعم iOS أربعة أنماط: .short، .medium، .long، .full. مزيج من أنماط التاريخ والوقت يسمح بتكوين عرض مرن. يطبق DateFormatter الترجمة تلقائيًا: للإعدادات المحلية الروسية، سيتم عرض التاريخ بتنسيق “21 يوليو 2026”.

ISO8601DateFormatter هو منسق متخصص لـ ISO 8601، التنسيق الأكثر شيوعًا لواجهات برمجة التطبيقات وتبادل البيانات. يعمل هذا المنسق بشكل أسرع من DateFormatter ولا يعتمد على الإعدادات المحلية، مما يجعله مفضلًا لتسلسل التواريخ في JSON.

swift
// الأنماط المحددة مسبقًا
let formatter = DateFormatter()
formatter.dateStyle = .medium
formatter.timeStyle = .short
let userString = formatter.string(from: Date())

// ISO 8601 لواجهات API
let isoFormatter = ISO8601DateFormatter()
let apiString = isoFormatter.string(from: Date())

// تحليل من سلسلة
let parsed = isoFormatter.date(from: "2026-07-21T10:30:00Z")!

عند العمل مع DateFormatter، من المهم تذكر الأداء: إنشاء منسق جديد هو عملية مكلفة. يوصى بتخزين المنسق مؤقتًا أو إنشائه مرة واحدة وإعادة استخدامه. تسمح خصائص المنسق بتعيين timeZone — افتراضيًا يتم استخدام المنطقة الزمنية للنظام، ولكن لتواريخ الخادم غالبًا ما يكون TimeZone(identifier: “UTC”) مطلوبًا.

أمثلة استخدام Date

لننظر في السيناريوهات النموذجية للعمل مع Date في تطبيق iOS. السيناريو الأول هو حساب العمر من تاريخ ميلاد المستخدم. الثاني هو مؤقت العد التنازلي لحدث. الثالث هو تجميع السجلات حسب التاريخ لعرضها كأقسام جدول.

حساب العمر من تاريخ الميلاد

Calendar.dateComponents مع العلم [.year] يحسب الفرق بين تاريخين. تعيين المنطقة الزمنية الصحيحة أمر بالغ الأهمية — إذا لم تحدد timeZone في Calendar، قد تختلف النتيجة بيوم بسبب عبور منتصف الليل في منطقة زمنية أخرى.

swift
func calculateAge(from birthDate: Date) -> Int {
    let calendar = Calendar.current
    let now = Date()
    let components = calendar.dateComponents(
        [.year], from: birthDate, to: now
    )
    return components.year ?? 0
}

مؤقت العد التنازلي يتم تنفيذه باستخدام TimeInterval. احسب الفرق بين التاريخ المستهدف والتاريخ الحالي، واحصل على الباقي بالثواني وحوله إلى أيام وساعات ودقائق. للتحديثات المنتظمة، استخدم Timer بفاصل زمني قدره 1 ثانية. كائن ObservableObject مع خاصية @Published يسمح لـ SwiftUI بتحديث الواجهة تلقائيًا.

التجميع حسب التاريخ يتم تنفيذه باستخدام قاموس مع Date كمفتاح. Calendar.dateInterval(of: .day, for:) يطبيع التاريخ إلى بداية اليوم، مما يسمح لك بتجميع السجلات التي تنتمي إلى نفس اليوم. نفس النهج يعمل للأسابيع والأشهر والسنوات — ببساطة قم بتغيير المكون في dateInterval إلى .weekOfYear أو .month.

السيناريوAPI الرئيسيملاحظات
حساب العمرCalendar.dateComponentsمراعاة timeZone
العد التنازليDate.timeIntervalSinceTimer+Combine
تجميع التواريخCalendar.dateIntervalتطبيع إلى اليوم
تسلسل JSONISO8601DateFormatterLocale لا يؤثر

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

كيف يختلف Date عن سلسلة التاريخ؟

Date هو تمثيل داخلي للوقت بدون ارتباط بالتقويم والإعدادات المحلية. السلسلة هي عرض منسق يعتمد على إعدادات المستخدم. يمكن مقارنة Date وتسلسله ومعالجته رياضيًا بدقة 100%، بينما تمثيل السلسلة يتطلب دائمًا تحليلًا عبر منسق.

لماذا لا يحتوي Date على معلومات المنطقة الزمنية؟

Date هو طابع زمني مطلق (عدد الثواني من تاريخ المرجع) لا يعتمد على المنطقة الزمنية. المنطقة الزمنية هي سياق عرض. نفس Date في UTC وفي موسكو يمثل نفس اللحظة المادية ولكنه يعرض كوقت تقويم مختلف.

أي نوع يجب استخدامه لتخزين الوقت في Core Data؟

Date مدعوم أصليًا من Core Data كنوع سمة. يقوم Core Data تلقائيًا بتسلسل Date في التخزين. للاستعلامات مع تصفية حسب التاريخ، استخدم NSPredicate مع عوامل المقارنة — يعالج Core Data المنطقة الزمنية بشكل صحيح على مستوى SQLite.

ما الفرق بين Date و CFAbsoluteTime؟

CFAbsoluteTime هو نوع Core Foundation يستخدم نفس تاريخ المرجع (1 يناير 2001). Date و CFAbsoluteTime قابلان للتبادل عبر التحويل المباشر. Date(timeIntervalSinceReferenceDate:) يقبل CFAbsoluteTime، و Date.timeIntervalSinceReferenceDate يعيد CFAbsoluteTime.

هل يمكن استخدام Date للقياسات عالية الدقة؟

Date لديه دقة ميلي ثانية ولكنه لا يضمن دقة نانو ثانية بسبب قيود أجهزة iOS/macOS. للقياسات عالية الدقة، استخدم mach_absolute_time أو ContinuousClock من Swift 5.7+، والتي تعمل على عدادات دورات المعالج.

ملخص

  • Date — نوع قيمة Foundation لتخزين لحظة زمنية مطلقة كـ TimeInterval من تاريخ المرجع 1 يناير 2001.
  • TimeInterval (Double) — عدد الثواني بين تاريخين، يوفر المقارنة والحساب مع Date.
  • Calendar و DateComponents — الطريقة الوحيدة لاستخراج السنة والشهر واليوم ومكونات التقويم الأخرى من Date.
  • DateFormatter و ISO8601DateFormatter — أدوات أساسية لعرض وتسلسل التواريخ بتنسيق سلسلة.
  • Date.distantPast و Date.distantFuture — قيم حدية للتصفية والترتيب في الخوارزميات.
  • Date لا يحتوي على منطقة زمنية — تضاف المنطقة الزمنية على مستوى Calendar عند استخراج المكونات للعرض.
  • Core Data و Codable يدعمان Date أصليًا، مما يبسط تخزين ونقل التواريخ دون تحويلات إضافية.

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

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

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

اقرأ أيضًا