مدیریت زمان بسیار پیچیده است. فرض‌های نادرست متداول در مورد زمان شامل موارد زیر است.

  1. یک روز شامل ۲۴ ساعت است.
  2. هر ساعت شامل ۶۰ دقیقه است.
  3. هفته شامل هفت روز است.
  4. یک سال شامل ۳۶۵ روز است.

به عنوان مثال، 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) ثانیه‌های تکراری را در نظر نمی‌گیرد. اگر دو لحظه زمانی را مقایسه کنید، تفاوت هیچ ثانیه تکراری را که ممکن است بین آن دو لحظه زمانی رخ داده است، شامل نمی‌شود.