Chuyển đến nội dung chính
Mô-đun 8 · Bài học 4 trong tổng số 539/50 trong khóa học~12 min
Bài học theo mô-đun (4/5)

Gói `thời gian`

Gói time mô hình ba khái niệm riêng biệt: tức thời (time.Time), thời lượng (time.Duration) và công cụ định kỳ (đồng hồ tính giờ, mã đánh dấu). Việc phân biệt chúng là rất quan trọng: một khoảnh khắc là một điểm trên dòng thời gian, một khoảng thời gian là một khoảng thời gian.

time.Time — tức thì

Go
now := time.Now()                // current instant in the local timezone
utc := now.UTC()                 // same instant in UTC
later := now.Add(2 * time.Hour)  // add a duration
diff := later.Sub(now)           // 2h0m0s (it's a Duration)

fmt.Println(now.Year(), now.Month(), now.Day())
fmt.Println(now.Weekday())

time.Time là bất biến: tất cả các phương thức Add, Truncate, Round đều trả về Time mới.

Để so sánh các thời điểm, hãy sử dụng Before, After, Equal. Không sử dụng == nếu thời điểm có thể có các múi giờ/đồng hồ đơn điệu khác nhau.

time.Duration — khoảng thời gian

Go
d := 250 * time.Millisecond
fmt.Println(d)         // 250ms
fmt.Println(d.Seconds()) // 0.25 (float64)

const timeout = 5 * time.Second

time.Duration là bí danh của int64 được tính nano giây. Các hằng số time.Nanosecond, time.Microsecond, time.Millisecond, time.Second, time.Minute, time.Hour thuộc loại Duration.

Phân tích cú pháp và định dạng: bố cục tham chiếu

Go không sử dụng các chuỗi như YYYY-MM-DD. Nó sử dụng tham chiếu chính tắc ngay lập tức:

Code
Mon Jan 2 15:04:05 MST 2006

tức là 01/02 03:04:05PM '06 -0700. Bằng cách ghi nhớ bố cục này (ghi nhớ: 1-2-3-4-5-6-7), bạn có thể định dạng bất kỳ ngày nào:

Go
const layout = "2006-01-02 15:04:05"
s := time.Now().Format(layout)            // "2026-05-16 14:30:00"
t, err := time.Parse(layout, "2026-05-16 14:30:00")

Stdlib cung cấp các bố cục được tạo sẵn: time.RFC3339 ("2006-01-02T15:04:05Z07:00"), time.RFC1123, time.Kitchen ("3:04PM").

Go
fmt.Println(time.Now().Format(time.RFC3339))

Đo thời gian

Go
start := time.Now()
work()
elapsed := time.Since(start)  // = time.Now().Sub(start)
fmt.Println("ci ha messo", elapsed)

time.Since sử dụng đồng hồ đơn điệu: nó không bị nhiễu bởi các điều chỉnh đồng hồ hệ thống (NTP, tiết kiệm ánh sáng ban ngày). Đối với các phép đo hiệu suất đó là những gì bạn muốn.

Đồng hồ bấm giờ và đánh dấu

  • time.After(d) trả về chan time.Time nhận chỉ một lần sau d. Hữu ích trong select:
Go
select {
case res := <-ch:
    fmt.Println("ok", res)
case <-time.After(2 * time.Second):
    return errors.New("timeout")
}
  • time.NewTimer(d) là biến thể có thể dừng được (t.Stop()).
  • time.NewTicker(d) gửi liên tục mỗi d. Hãy nhớ defer ticker.Stop() để tránh rò rỉ goroutine.
Go
ticker := time.NewTicker(time.Second)
defer ticker.Stop()
for range ticker.C {
    fmt.Println("tick")
}

Bài tập

tập thể dục#go.m8.l4.e1
Nỗ lực: 0Đang tải…

In tức thời hiện tại được định dạng theo time.RFC3339.

Đang tải trình chỉnh sửa…

Giải pháp khả dụng sau 3 lần thử

tập thể dục#go.m8.l4.e2
Nỗ lực: 0Đang tải…

Đo thời gian trong bao lâu. Thời gian ngủ 10 mili giây mất thời gian sử dụng. Kể từ đó và in kết quả.

Đang tải trình chỉnh sửa…

Giải pháp khả dụng sau 3 lần thử

Quiz#go.m8.l4.e3
Sẵn sàng

Hằng số `time.Second` là loại gì?

Go
d := time.Second
// d ha tipo ???
Tùy chọn trả lời