Xử lý thời gian khá phức tạp. Giả định không chính xác thông thường về thời gian bao gồm những điểm sau đây.

  1. Một ngày bao gồm 24 giờ.
  2. Một giờ bao gồm 60 phút.
  3. Một tuần bao gồm bảy ngày.
  4. Một năm bao gồm 365 ngày.

Ví dụ, 1 cho thấy việc thêm 24 giờ vào một thời điểm cụ thể không luôn dẫn đến một ngày mới trên lịch.

Do đó, khi xử lý thời gian, luôn sử dụng gói "time" vì nó giúp xử lý những giả định không chính xác này một cách an toàn và chính xác hơn.

Sử dụng time.Time để Biểu Diễn Thời Gian Tức Thì

Khi xử lý thời gian tức thì, hãy sử dụng time.Time và các phương thức của nó để so sánh, cộng hoặc trừ thời gian.

Không Được Khuyến Nghị:

func isActive(now, start, stop int) bool {
  return start <= now && now < stop
}

Được Khuyến Nghị:

func isActive(now, start, stop time.Time) bool {
  return (start.Before(now) || start.Equal(now)) && now.Before(stop)
}

Sử Dụng time.Duration để Biểu Diễn Khoảng Thời Gian

Khi xử lý khoảng thời gian, hãy sử dụng time.Duration.

Không Được Khuyến Nghị:

func poll(delay int) {
  for {
    // ...
    time.Sleep(time.Duration(delay) * time.Millisecond)
  }
}
poll(10) // Có phải đơn vị là giây hay mili-giây không?

Được Khuyến Nghị:

func poll(delay time.Duration) {
  for {
    // ...
    time.Sleep(delay)
  }
}
poll(10*time.Second)

Quay trở lại ví dụ đầu tiên, khi thêm 24 giờ vào một thời điểm cụ thể, phương pháp được sử dụng phụ thuộc vào ý định. Nếu chúng ta muốn điểm thời gian tương tự vào ngày lịch kế tiếp (ngày sau ngày hiện tại), chúng ta nên sử dụng Time.AddDate. Tuy nhiên, nếu chúng ta muốn đảm bảo rằng một khoảnh khắc nhất định là muộn hơn 24 giờ so với khoảnh khắc trước đó, chúng ta nên sử dụng Time.Add.

newDay := t.AddDate(0 /* năm */, 0 /* tháng */, 1 /* ngày */)
maybeNewDay := t.Add(24 * time.Hour)

Sử dụng time.Timetime.Duration với Hệ thống Bên ngoài

Nếu có thể, hãy sử dụng time.Durationtime.Time khi tương tác với hệ thống bên ngoài, ví dụ:

Khi không thể sử dụng time.Duration trong các tương tác này, hãy sử dụng int hoặc float64 và bao gồm đơn vị trong tên trường.

Ví dụ, vì encoding/json không hỗ trợ time.Duration, đơn vị sẽ được bao gồm trong tên trường.

Không được khuyến nghị:

// {"interval": 2}
type Config struct {
  Interval int `json:"interval"`
}

Được khuyến nghị:

// {"intervalMillis": 2000}
type Config struct {
  IntervalMillis int `json:"intervalMillis"`
}

Khi không thể sử dụng time.Time trong các tương tác này, trừ khi được đồng ý khác, hãy sử dụng string và định dạng dấu thời gian theo RFC 3339. Theo mặc định, Time.UnmarshalText sử dụng định dạng này và nó có thể được sử dụng trong Time.Formattime.Parse thông qua time.RFC3339.

Mặc dù không phải là vấn đề thực tế, xin lưu ý rằng gói "time" không hỗ trợ phân tích dấu thời gian có bước nhảy giây (8728), và không tính bước nhảy giây trong các tính toán (15190). Nếu bạn so sánh hai khoảnh khắc thời gian, sự khác biệt sẽ không bao gồm bất kỳ bước nhảy giây nào có thể xảy ra giữa hai khoảnh khắc đó.