معالجة الوقت معقدة إلى حد ما. الافتراضات الخاطئة الشائعة حول الوقت تشمل ما يلي.
- يتكون اليوم من 24 ساعة.
- تحتوي الساعة على 60 دقيقة.
- الأسبوع يتكون من سبعة أيام.
- السنة تتألف من 365 يومًا.
على سبيل المثال، يشير 1 إلى أن إضافة 24 ساعة إلى نقطة زمنية معينة لا ينتج دائمًا في يوم تقويمي جديد.
لذلك، عند التعامل مع الوقت، استخدم دائمًا حزمة "time"
حيث تساعد في التعامل مع هذه الافتراضات الخاطئة بطريقة أكثر أمانًا ودقة.
استخدام time.Time
لتمثيل الوقت الفوري
عند التعامل مع الوقت الفوري، استخدم time.Time
وأساليبها للمقارنة أو إضافة أو طرح الوقت.
غير مُفضّل:
func isActive(now, start, stop int) bool {
return start <= now && now < stop
}
مُفضّل:
func isActive(now, start, stop time.Time) bool {
return (start.Before(now) || start.Equal(now)) && now.Before(stop)
}
استخدام time.Duration
لتمثيل مدد الزمن
عند التعامل مع مدد الزمن، استخدم time.Duration
.
غير مُفضّل:
func poll(delay int) {
for {
// ...
time.Sleep(time.Duration(delay) * time.Millisecond)
}
}
poll(10) // هل هو بالثواني أم بالميلي ثانية؟
مُفضّل:
func poll(delay time.Duration) {
for {
// ...
time.Sleep(delay)
}
}
poll(10*time.Second)
عند العودة إلى المثال الأول، عند إضافة 24 ساعة إلى الوقت الفوري، يعتمد الأمر على الغرض. إذا أردنا نفس نقطة الوقت في اليوم التقويمي التالي (اليوم بعد اليوم الحالي)، يجب علينا استخدام Time.AddDate
. ومع ذلك، إذا أردنا ضمان أن لحظة معينة تأتي بعد 24 ساعة من السابقة، يجب علينا استخدام Time.Add
.
newDay := t.AddDate(0 /* سنوات */, 0 /* شهور */, 1 /* أيام */)
maybeNewDay := t.Add(24 * time.Hour)
استخدام time.Time
و time.Duration
مع الأنظمة الخارجية
عندما يكون ذلك ممكنًا ، استخدم time.Duration
و time.Time
في التفاعل مع الأنظمة الخارجية ، على سبيل المثال:
- علامات سطر الأوامر:
flag
تدعمtime.Duration
من خلالtime.ParseDuration
. - JSON:
encoding/json
تدعم ترميزtime.Time
إلى سلسلة RFC 3339 باستخدام طريقتهاUnmarshalJSON
. - SQL:
database/sql
تدعم تحويل الأعمدةDATETIME
أوTIMESTAMP
إلىtime.Time
، وتعود إذا كان المشغل الأساسي يدعم ذلك. - YAML:
gopkg.in/yaml.v2
تدعم استخدامtime.Time
كسلسلة RFC 3339 وtime.Duration
من خلالtime.ParseDuration
.
عندما لا يمكن استخدام time.Duration
في هذه التفاعلات ، استخدم int
أو float64
وقم بتضمين الوحدة في اسم الحقل.
على سبيل المثال ، نظرًا لأن encoding/json
لا تدعم time.Duration
، يتم تضمين الوحدة في اسم الحقل.
غير مستحسن:
// {"interval": 2}
type Config struct {
Interval int `json:"interval"`
}
مُفَضَّل:
// {"intervalMillis": 2000}
type Config struct {
IntervalMillis int `json:"intervalMillis"`
}
عندما لا يمكن استخدام time.Time
في هذه التفاعلات ، مالم يتم الاتفاق على خلاف ذلك ، استخدم string
وقم بتنسيق الطوابع الزمنية وفقًا لـ RFC 3339. بشكل افتراضي ، Time.UnmarshalText
يستخدم هذا التنسيق ويمكن استخدامه في Time.Format
و time.Parse
من خلال time.RFC3339
.
على الرغم من أنها ليست مشكلة عملية ، يرجى ملاحظة أن حزمة "time" لا تدعم تحليل الطوابع الزمنية للثواني الزائدة (8728) ، ولا تأخذ في اعتبارها الثواني الزائدة في الحسابات (15190). إذا قارنت لحظتين زمنيتين ، فإن الفرق لن يشمل أي ثواني زائدة قد حدثت بين تلك اللحظتين.