مقدمة في العمل مع التواريخ والوقت في Go
\nالعمل مع التواريخ والوقت هو إحدى المهام الأساسية في أي تطبيق جاد. سواء كان ذلك تسجيل الأحداث، حساب المهلات الزمنية، العمل مع الجداول الزمنية أو تحليل السلاسل الزمنية، توفر لغة Go مجموعة أدوات قوية وأنيقة في الحزمة القياسية time. في هذه المقالة، سنشرح العمل مع التواريخ والوقت في Go من الألف إلى الياء: من إنشاء كائنات الوقت إلى العمليات المعقدة مع المناطق الزمنية والمؤقتات.
الأساسيات: بنية time.Time وإنشاء التواريخ
\nالعنصر المركزي في حزمة time هو البنية time.Time. وهي تمثل لحظة زمنية بدقة نانوثانية ومعلومات عن المنطقة الزمنية.
الحصول على الوقت الحالي
\nالسيناريو الأكثر شيوعاً هو الحصول على اللحظة الحالية:
\npackage main\n\nimport (\n "fmt"\n "time"\n)\n\nfunc main() {\n now := time.Now()\n fmt.Println("الوقت الحالي:", now)\n}\n\nإنشاء تاريخ محدد
\nلإنشاء تاريخ، تُستخدم الدالة time.Date(). لاحظ: في Go، يتم تحديد الأشهر باستخدام الثوابت (time.January، time.February، إلخ) أو برقم من 1 إلى 12.
func main() {\n // 15 مارس 2025، الساعة 14:30:00، UTC\n specificDate := time.Date(2025, time.March, 15, 14, 30, 0, 0, time.UTC)\n fmt.Println("تاريخ محدد:", specificDate)\n \n // إنشاء مع نانوثوانٍ\n preciseDate := time.Date(2025, 3, 15, 14, 30, 0, 123456789, time.UTC)\n fmt.Println("تاريخ دقيق:", preciseDate)\n}\n\nتنسيق وتحليل التواريخ
\nفي Go، يُستخدم نهج فريد للتنسيق: بدلاً من الرموز مثل %Y-%m-%d، تستخدم الوقت المرجعي Mon Jan 2 15:04:05 MST 2006 (الذي يُقرأ كـ 01 02 03 04 05 06 07 — السنة، الشهر، اليوم، الساعة، الدقيقة، الثانية، السنة).
التنسيق (time ← سلسلة نصية)
\nتقوم طريقة Format() بتحويل الوقت إلى سلسلة نصية وفقاً للنمط المحدد:
func main() {\n now := time.Now()\n \n // التنسيقات القياسية\n fmt.Println("RFC3339:", now.Format(time.RFC3339))\n fmt.Println("التاريخ:", now.Format("2006-01-02"))\n fmt.Println("الوقت:", now.Format("15:04:05"))\n fmt.Println("تنسيق كامل:", now.Format("02.01.2006 15:04:05"))\n fmt.Println("مع يوم الأسبوع:", now.Format("Mon, 02 Jan 2006"))\n}\n\nالتحليل (سلسلة نصية ← time.Time)
\nتقوم الدالة time.Parse() بتحليل سلسلة نصية إلى بنية وقت. مهم: يجب أن يتطابق النمط تماماً مع تنسيق السلسلة النصية المدخلة.
func main() {\n // تحليل بتنسيق معروف\n dateStr := "2025-03-15 14:30:00"\n parsed, err := time.Parse("2006-01-02 15:04:05", dateStr)\n if err != nil {\n panic(err)\n }\n fmt.Println("تم التحليل:", parsed)\n \n // تحليل مع منطقة زمنية\n dateWithZone := "2025-03-15T14:30:00+03:00"\n parsedWithZone, _ := time.Parse(time.RFC3339, dateWithZone)\n fmt.Println("مع منطقة زمنية:", parsedWithZone)\n}\n\nحسابات الوقت: الفترات والمقارنات
\nتوفر حزمة time النوع Duration لتمثيل الفترات الزمنية وطرقاً للعمليات الحسابية.
الجمع والطرح
\nfunc main() {\n now := time.Now()\n \n // إضافة ساعتين و30 دقيقة\n future := now.Add(2*time.Hour + 30*time.Minute)\n fmt.Println("بعد 2.5 ساعة:", future)\n \n // طرح 7 أيام\n past := now.Add(-7 * 24 * time.Hour)\n fmt.Println("قبل أسبوع:", past)\n \n // استخدام AddDate للعمل مع التواريخ التقويمية\n nextMonth := now.AddDate(0, 1, 0)\n fmt.Println("بعد شهر:", nextMonth)\n}\n\nحساب الفرق بين التواريخ
\nتقوم طريقة Sub() بإرجاع Duration:
func main() {\n start := time.Date(2025, 1, 1, 0, 0, 0, 0, time.UTC)\n end