مدیریت زمان بسیار پیچیده است. فرضهای نادرست متداول در مورد زمان شامل موارد زیر است.
- یک روز شامل ۲۴ ساعت است.
- هر ساعت شامل ۶۰ دقیقه است.
- هفته شامل هفت روز است.
- یک سال شامل ۳۶۵ روز است.
به عنوان مثال، 1 نشان دهنده این است که افزودن ۲۴ ساعت به یک نقطه زمانی خاص ممکن است به یک روز جدید در تقویم منجر نشود.
بنابراین، هنگام مدیریت زمان، همیشه از بستهی "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)
بازگشت به مثال اول، هنگام اضافه کردن ۲۴ ساعت به یک زمان لحظهای، روش استفاده شده بستگی به قصد دارد. اگر میخواهیم همان نقطه زمانی را در روز تقویمی بعد (روز بعد از روز فعلی) داشته باشیم، باید از Time.AddDate
استفاده کنیم. با این حال، اگر میخواهیم اطمینان حاصل کنیم که یک لحظه خاص ۲۴ ساعت بعد از قبلی است، باید از Time.Add
استفاده کنیم.
newDay := t.AddDate(0 /* سال */, 0 /* ماه */, 1 /* روز */)
maybeNewDay := t.Add(24 * time.Hour)
استفاده از time.Time
و time.Duration
با سیستمهای خارجی
هر زمان که امکان وجود داشته باشد، از time.Duration
و time.Time
در تعامل با سیستمهای خارجی استفاده کنید؛ برای مثال:
- دستورات خط فرمان:
flag
از طریقtime.ParseDuration
ازtime.Duration
پشتیبانی میکند. - JSON:
encoding/json
از طریق متدUnmarshalJSON
، از تبدیلtime.Time
به رشته RFC 3339 پشتیبانی میکند. - 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) ثانیههای تکراری را در نظر نمیگیرد. اگر دو لحظه زمانی را مقایسه کنید، تفاوت هیچ ثانیه تکراری را که ممکن است بین آن دو لحظه زمانی رخ داده است، شامل نمیشود.