مقدمة: لماذا يعمل كود التواريخ الخاص بك "بشكل متقطع"؟
\n\nتخيل: أنت تكتب تطبيق تقويم أو تذكير. تحتاج ببساطة إلى أخذ التاريخ الحالي وإضافة يوم واحد إليه. قد يبدو الأمر بسيطًا، فما الذي يمكن أن يحدث خطأ؟ تفتح Stack Overflow، تجد سؤالًا بآلاف المشاهدات "How do I add 1 day to an NSDate؟" — وتدرك أنه حتى هذه العملية البسيطة يمكن أن تتحول إلى كابوس.
\n\nفي هذه المقالة، سنحلل أهم الأخطاء عند إضافة يوم إلى NSDate في Swift، ونتعلم كيفية تجنبها، ونكتب كودًا صحيحًا وموثوقًا. ستعرف لماذا الطريقة القديمة باستخدام NSDate و timeInterval هي طريق للأخطاء، وكيف تنقذ واجهات برمجة التطبيقات الحديثة من Apple الموقف.
هيا بنا نفهم التواريخ مرة واحدة وإلى الأبد!
\n\nالخطأ رقم 1: استخدام timeInterval لإضافة يوم
\n\nكود كارثي
\nأكثر "مشكلة" شائعة يقع فيها المبتدئون:
\n\nlet today = NSDate()\nlet oneDay: TimeInterval = 24 * 60 * 60 // 86,400 ثانية\nlet tomorrow = today.addingTimeInterval(oneDay)\n\nللوهلة الأولى، يبدو منطقيًا. اليوم يحتوي على 24 ساعة، والساعة على 60 دقيقة، والدقيقة على 60 ثانية. نضرب، نضيف — ربح!
\n\nلكن لا. هذا يعمل فقط في 99% من الحالات، وفي 1% يعطل التطبيق بأكمله للمستخدمين. لماذا؟
\n\nالمزالق الخفية
\n- \n
- التوقيت الصيفي/الشتوي. في يوم تغيير الساعة، قد يستمر اليوم 23 أو 25 ساعة. ستتحول 86,400 ثانية إلى 83,400 أو 90,000. \n
- الثواني الكبيسة. على الرغم من ندرتها، إلا أنها موجودة رسميًا. \n
- المناطق الزمنية. إذا كان المستخدم يسافر، فقد يضطرب توقيته المحلي. \n
- الدقة حتى الثانية. أنت لا تضيف فقط "اليوم التالي"، بل تضيف بالضبط 24 ساعة — وهذا شيء مختلف. \n
هل تريد مثالاً؟ في 28 مارس 2021، تم تقديم الساعة في أوكرانيا لمدة ساعة في الساعة 3:00 صباحًا. إذا أضفت timeInterval إلى الساعة 2:30 صباحًا، فلن تحصل على 3:30، بل... 4:30؟ أم 2:30؟ يعتمد ذلك على كيفية معالجة النظام للانتقال. باختصار، فوضى.
الخطأ رقم 2: خلط NSDate و Date في نفس المشروع
\n\nفي Swift، هناك نوعان من التواريخ: القديم NSDate (من Objective-C) والحديث Date (الأصلي لـ Swift). يستمر العديد من المطورين، خاصة أولئك الذين يقرؤون البرامج التعليمية القديمة أو إجابات Stack Overflow من عام 2014، في استخدام NSDate.
المشكلة هي أن NSDate هو كلاس (نوع مرجعي)، بينما Date هو هيكل (نوع قيمي). يؤدي خلطهما في الكود إلى:
- \n
- أخطاء غير واضحة تتعلق بالقابلية للتغيير \n
- تحويلات غير ضرورية (
as Date,as NSDate) \n - ارتباك في واجهات برمجة التطبيقات \n
القاعدة: في كود Swift الجديد، استخدم فقط Date. اترك NSDate للتوافق مع مكتبات Objective-C.
الخطأ رقم 3: تجاهل Calendar و TimeZone
\n\nعند إضافة "يوم واحد" إلى تاريخ، فإنك تفعل ذلك في سياق التقويم. بدون تحديد التقويم، يستخدم النظام Calendar.current — وهو تقويم المستخدم (عادةً ما يكون ميلاديًا).
ولكن ماذا لو كان المستخدم من المملكة العربية السعودية يستخدم التقويم الإسلامي؟ أو الياباني؟ بدون تحديد التقويم صراحةً، فإنك تخاطر بالحصول على نتائج غير متوقعة.
\n\nمثال على كود خاطئ
\nvar dateComponents = DateComponents()\ndateComponents.day = 1\nlet tomorrow = Calendar.current.date(byAdding: dateComponents, to: Date())\n\nهذا الكود تقريبًا صحيح، لكنه يستخدم ضمنيًا المنطقة الزمنية للجهاز. إذا كنت تعمل مع تواريخ الخادم بتوقيت UTC، وكان المستخدم في موسكو (UTC+3)، فقد يأتي "الغد" قبل 3 ساعات.
\n\nالحل الصحيح: Calendar + DateComponents
\n\nالمعيار الذهبي لإضافة يوم
\nإليك كيفية إضافة يوم واحد بشكل صحيح إلى