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.
- Một ngày bao gồm 24 giờ.
- Một giờ bao gồm 60 phút.
- Một tuần bao gồm bảy ngày.
- 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.Time
và time.Duration
với Hệ thống Bên ngoài
Nếu có thể, hãy sử dụng time.Duration
và time.Time
khi tương tác với hệ thống bên ngoài, ví dụ:
- Cờ dòng lệnh:
flag
hỗ trợtime.Duration
thông quatime.ParseDuration
. - JSON:
encoding/json
hỗ trợ mã hóatime.Time
thành chuỗi RFC 3339 bằng phương thứcUnmarshalJSON
. - SQL:
database/sql
hỗ trợ chuyển đổi cộtDATETIME
hoặcTIMESTAMP
sangtime.Time
, và trả về nếu trình điều khiển cơ sở dữ liệu hỗ trợ điều này. - YAML:
gopkg.in/yaml.v2
hỗ trợ sử dụngtime.Time
như là chuỗi RFC 3339 vàtime.Duration
thông quatime.ParseDuration
.
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.Format
và time.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 đó.