跳转到主要内容
模块 8 · 第 4 课(共 5)课程中的39/50~12 min
模块课程(4/5)

“时间”包

time 包模拟了三个不同的概念:即时 (time.Time)、持续时间 (time.Duration) 和 周期性工具(计时器、股票代码)。区分它们至关重要:瞬间是时间线上的一个点,持续时间是一个间隔。

time.Time — 瞬间

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 是 不可变的:所有方法 Add、Truncate、Round 返回一个新的 Time。

要比较瞬间,请使用 Before、After、Equal。 如果瞬间可以有不同的时区/单调时钟,请勿使用 ==。

time.Duration — 间隔

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

const timeout = 5 * time.Second

time.Duration 是 int64 的别名,用于计算纳秒。常量 time.Nanosecond、time.Microsecond、time.Millisecond、time.Second、time.Minute、time.Hour 的类型为 Duration。

解析和格式化:参考布局

Go 不使用像 YYYY-MM-DD 这样的字符串。它使用规范参考即时:

Code
Mon Jan 2 15:04:05 MST 2006

即 01/02 03:04:05PM '06 -0700。通过记住这个布局(助记符:1-2-3-4-5-6-7),您可以格式化任何日期:

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 提供现成的布局:time.RFC3339 ("2006-01-02T15:04:05Z07:00")、time.RFC1123、time.Kitchen ("3:04PM")。

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

测量时间

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

time.Since 使用单调时钟:它不受系统时钟调整(NTP、夏令时)的干扰。对于性能测量来说,这就是您想要的。

计时器和行情指示器

  • time.After(d) 返回一个 chan time.Time,它在 d 之后仅接收一次。在 select 中有用:
Go
select {
case res := <-ch:
    fmt.Println("ok", res)
case <-time.After(2 * time.Second):
    return errors.New("timeout")
}
  • time.NewTimer(d) 是一个可停止的变体 (t.Stop())。
  • time.NewTicker(d) 每 d 重复发送一次。 记住 defer ticker.Stop() 以避免 goroutine 泄漏。
Go
ticker := time.NewTicker(time.Second)
defer ticker.Stop()
for range ticker.C {
    fmt.Println("tick")
}

练习

锻炼#go.m8.l4.e1
尝试:0加载中...

根据 time.RFC3339 格式化当前时刻。

正在加载编辑器...

3 次尝试后可用的解决方案

锻炼#go.m8.l4.e2
尝试:0加载中...

使用 time.Since 测量 10ms 的睡眠需要多长时间并打印结果。

正在加载编辑器...

3 次尝试后可用的解决方案

Quiz#go.m8.l4.e3
准备好

常量“time.Second”是什么类型?

Go
d := time.Second
// d ha tipo ???
答案选项