العمل المتقدم مع التواريخ والأوقات في Kotlin
\n\nفي التطوير الحديث باستخدام Kotlin، المعالجة الصحيحة للتواريخ والأوقات ليست مجرد راحة، بل ضرورة. على المستوى المتقدم، يتعين على المطور التعامل مع المناطق الزمنية، والفترات، والمدد، وعمليات التنسيق المعقدة. في هذه المقالة، سنستعرض الأدوات والتقنيات الرئيسية التي ستساعدك على كتابة كود موثوق وفعال.
\n\n1. الفئات الأساسية: LocalDate، LocalTime، LocalDateTime و Instant
\n\nترث Kotlin بالكامل مكتبة java.time القوية (JSR-310)، والتي أصبحت المعيار للعمل مع التواريخ والأوقات في Java 8 والإصدارات الأحدث. بالنسبة لـ Kotlin Multiplatform، توجد مكتبة kotlinx-datetime، ولكن في مشاريع JVM، تظل java.time هي الأكثر شيوعًا.
LocalDate، LocalTime، LocalDateTime
\nتمثل هذه الفئات التاريخ والوقت دون الارتباط بمنطقة زمنية. وهي مثالية لتخزين أعياد الميلاد، والجداول الزمنية، والبيانات الأخرى التي لا تكون المنطقة الزمنية مهمة فيها.
\n\nimport java.time.LocalDate\nimport java.time.LocalTime\nimport java.time.LocalDateTime\n\nfun main() {\n val date = LocalDate.now()\n val time = LocalTime.of(14, 30, 0)\n val dateTime = LocalDateTime.of(date, time)\n \n println("التاريخ: $date")\n println("الوقت: $time")\n println("التاريخ والوقت: $dateTime")\n \n // جمع وطرح الأيام\n val tomorrow = date.plusDays(1)\n println("غدًا: $tomorrow")\n}\n\nInstant — طابع زمني للآلات
\nيمثل Instant نقطة على الخط الزمني بالتوقيت العالمي المنسق (UTC). وهو لا غنى عنه لتسجيل السجلات، وتبادل البيانات بين الخوادم، والعمل مع واجهات برمجة التطبيقات (API).
import java.time.Instant\n\nfun main() {\n val now = Instant.now()\n println("اللحظة الحالية بالتوقيت العالمي: $now")\n \n // التحويل من ميلي ثانية\n val fromEpoch = Instant.ofEpochMilli(1_700_000_000_000)\n println("من ميلي ثانية: $fromEpoch")\n}\n\n2. المناطق الزمنية: ZonedDateTime و OffsetDateTime
\n\nعندما يعمل التطبيق مع مستخدمين من مناطق مختلفة، يجب مراعاة المناطق الزمنية. لهذا الغرض، توجد ZonedDateTime (مع معلومات كاملة عن المنطقة) و OffsetDateTime (فقط الإزاحة عن UTC).
import java.time.ZonedDateTime\nimport java.time.ZoneId\nimport java.time.ZoneOffset\n\nfun main() {\n // الوقت الحالي في نيويورك\n val newYork = ZonedDateTime.now(ZoneId.of("America/New_York"))\n println("نيويورك: $newYork")\n \n // التحويل من UTC\n val utcNow = ZonedDateTime.now(ZoneOffset.UTC)\n val moscowTime = utcNow.withZoneSameInstant(ZoneId.of("Europe/Moscow"))\n println("موسكو: $moscowTime")\n \n // OffsetDateTime للإزاحات البسيطة\n val offsetTime = java.time.OffsetDateTime.now(ZoneOffset.ofHours(3))\n println("+3 ساعات: $offsetTime")\n}\n\nهام: بالنسبة لواجهة المستخدم، استخدم دائمًا ZonedDateTime لمعالجة التوقيت الصيفي/الشتوي بشكل صحيح. OffsetDateTime مناسب للإزاحات الثابتة، مثل عند العمل مع السجلات.
3. الفرق بين التواريخ: Period و Duration
\n\nلحساب الفرق في الوقت، توفر Kotlin فئتين: Period (للتوارخ، بالأيام/الأشهر/السنوات) و Duration (للفترات الزمنية الدقيقة بالثواني/النانو ثانية).
Period — العمل مع الوحدات التقويمية
\nimport java.time.LocalDate\nimport java.time.Period\n\nfun main() {\n val birthDate = LocalDate.of(1990, 5, 15)\n val today = LocalDate.now()\n val age = Period.between(birthDate, today)\n \n println("العمر: ${age.years} سنة، ${age.months} شهر، ${age.days} يوم")\n \n // إضافة فترة إلى تاريخ\n val nextMonth = today.plus(Period.ofMonths(1))\n println("بعد شهر: $nextMonth")\n}\n\n