Go 语言标准库 — time 包(时间处理)
🕒 时间类型(Time)
获取当前时间(包含墙钟时间和单调时钟)。
time.Now() Time
-
说明:
- 返回的 Time 包含墙钟时间和单调时钟读数
- 单调时钟用于时间比较和减法运算(不受系统时间调整影响)
- 墙钟时间用于显示和格式化(受系统时间调整影响)
- 单调时钟在序列化时会丢失
-
注意事项:
- 比较时间应使用 Equal、Before、After 方法
- 不要直接比较 Time 结构体(可能因单调时钟导致错误)
-
示例(完整)
package main import ( "fmt" "time" ) func main() { now := time.Now() fmt.Println("当前时间:", now) fmt.Println("年:", now.Year()) fmt.Println("月:", now.Month()) fmt.Println("日:", now.Day()) fmt.Println("小时:", now.Hour()) fmt.Println("分钟:", now.Minute()) fmt.Println("秒:", now.Second()) fmt.Println("纳秒:", now.Nanosecond()) fmt.Println("星期:", now.Weekday()) } -
使用场景示例
-
测量代码执行时间
- 示例:
start := time.Now() // 执行某些操作 elapsed := time.Since(start) fmt.Println("耗时:", elapsed)
- 示例:
-
记录日志时间戳
- 示例:
logTime := time.Now() fmt.Printf("[%s] 日志内容\n", logTime.Format(time.RFC3339))
- 示例:
-
创建指定日期时间。
time.Date(year int, month Month, day, hour, min, sec, nsec int, loc *Location) Time
- 说明:
- month: 1-12 或 time.January 等常量
- loc: 时区,nil 表示 UTC
- 示例(完整)
package main import ( "fmt" "time" ) func main() { t := time.Date(2024, time.March, 15, 10, 30, 0, 0, time.Local) fmt.Println("创建时间:", t) utc := time.Date(2024, 1, 1, 0, 0, 0, 0, time.UTC) fmt.Println("UTC 时间:", utc) }
根据 Unix 时间戳创建时间。
time.Unix(sec int64, nsec int64) Time
- 说明:
- sec: 自 1970-01-01 00:00:00 UTC 以来的秒数
- nsec: 纳秒部分(0-999999999)
- 示例(完整)
package main import ( "fmt" "time" ) func main() { t := time.Unix(1700000000, 0) fmt.Println("Unix 时间:", t) t2 := time.Unix(1700000000, 500000000) fmt.Println("带纳秒:", t2) }
解析时间字符串(返回 UTC 时间)。
time.Parse(layout, value string) (Time, error)
- 说明:
- layout: 使用 Go 的参考时间格式
- 参考时间:2006-01-02 15:04:05
- 返回的时间为 UTC 时区
- 示例(完整)
package main import ( "fmt" "time" ) func main() { t, err := time.Parse("2006-01-02 15:04:05", "2024-03-15 10:30:00") if err != nil { fmt.Println("解析失败:", err) return } fmt.Println("解析结果:", t) }
解析时间字符串(指定时区)。
time.ParseInLocation(layout, value string, loc *Location) (Time, error)
- 说明:
- 跟 Parse 类似,但使用指定的时区
- 常用于解析本地时间
- 示例(完整)
package main import ( "fmt" "time" ) func main() { t, err := time.ParseInLocation("2006-01-02", "2024-03-15", time.Local) if err != nil { fmt.Println("解析失败:", err) return } fmt.Println("本地时间:", t) }
📅 Time 类型方法
返回年份。
t.Year() int
- 示例
t := time.Now() fmt.Println("年份:", t.Year())
返回月份(1-12 或 January-December)。
t.Month() Month
- 示例
t := time.Now() fmt.Println("月份:", t.Month()) fmt.Println("月份数字:", int(t.Month()))
返回日期(1-31)。
t.Day() int
- 示例
t := time.Now() fmt.Println("日期:", t.Day())
返回小时(0-23)。
t.Hour() int
- 示例
t := time.Now() fmt.Println("小时:", t.Hour())
返回分钟(0-59)。
t.Minute() int
- 示例
t := time.Now() fmt.Println("分钟:", t.Minute())
返回秒(0-59)。
t.Second() int
- 示例
t := time.Now() fmt.Println("秒:", t.Second())
返回纳秒(0-999999999)。
t.Nanosecond() int
- 示例
t := time.Now() fmt.Println("纳秒:", t.Nanosecond())
返回星期几(Sunday-Saturday)。
t.Weekday() Weekday
- 示例
t := time.Now() fmt.Println("星期:", t.Weekday()) fmt.Println("星期数字:", int(t.Weekday()))
返回一年中的第几天(1-366)。
t.YearDay() int
- 示例
t := time.Now() fmt.Println("年第几天:", t.YearDay())
返回 ISO 8601 标准的年和周。
t.ISOWeek() (year, week int)
- 示例
t := time.Now() year, week := t.ISOWeek() fmt.Printf("ISO: %d 年第 %d 周\n", year, week)
返回年月日。
t.Date() (year int, month Month, day int)
- 示例
t := time.Now() year, month, day := t.Date() fmt.Printf("日期:%d-%02d-%02d\n", year, month, day)
返回时分秒。
t.Clock() (hour, min, sec int)
- 示例
t := time.Now() hour, min, sec := t.Clock() fmt.Printf("时间:%02d:%02d:%02d\n", hour, min, sec)
返回 Unix 时间戳(秒)。
t.Unix() int64
- 示例
t := time.Now() fmt.Println("Unix 秒:", t.Unix())
返回 Unix 时间戳(纳秒)。
t.UnixNano() int64
- 示例
t := time.Now() fmt.Println("Unix 纳秒:", t.UnixNano())
返回 Unix 时间戳(毫秒)。
t.UnixMilli() int64
- 示例
t := time.Now() fmt.Println("Unix 毫秒:", t.UnixMilli())
返回 Unix 时间戳(微秒)。
t.UnixMicro() int64
- 示例
t := time.Now() fmt.Println("Unix 微秒:", t.UnixMicro())
格式化时间为字符串。
t.Format(layout string) string
-
说明:
- 使用 Go 的参考时间格式:2006-01-02 15:04:05
- 2006 代表年,01 代表月,02 代表日
- 15 代表时(24 小时制),04 代表分,05 代表秒
- 不是使用常见的 %Y-%m-%d 格式
-
常用格式元素:
- 年:2006 或 06
- 月:01 或 1 或 Jan 或 January
- 日:02 或 2 或 _2
- 时:15 或 3 或 03
- 分:04
- 秒:05
- 时区:MST 或 Z07:00 或 -0700
-
示例(完整)
package main import ( "fmt" "time" ) func main() { t := time.Now() fmt.Println(t.Format("2006-01-02 15:04:05")) fmt.Println(t.Format("2006/01/02")) fmt.Println(t.Format("15:04:05")) fmt.Println(t.Format("03:04:05 PM")) fmt.Println(t.Format("2006-01-02T15:04:05Z07:00")) } -
使用场景示例
-
数据库时间格式
- 示例:
dbTime := t.Format("2006-01-02 15:04:05") fmt.Println("数据库时间:", dbTime)
- 示例:
-
文件名时间戳
- 示例:
filename := "backup_" + t.Format("20060102_150405") + ".zip" fmt.Println("文件名:", filename)
- 示例:
-
ISO 8601 格式
- 示例:
isoTime := t.Format(time.RFC3339) fmt.Println("ISO 时间:", isoTime)
- 示例:
-
追加格式化时间到字节切片。
t.AppendFormat(b []byte, layout string) []byte
- 示例
t := time.Now() b := []byte("时间:") b = t.AppendFormat(b, "2006-01-02") fmt.Println(string(b))
返回时间的字符串表示(用于调试)。
t.String() string
- 示例
t := time.Now() fmt.Println(t.String())
返回时间关联的时区。
t.Location() *Location
- 示例
t := time.Now() loc := t.Location() fmt.Println("时区:", loc)
*t.In(loc Location) Time
转换为指定时区。
- 示例
t := time.Now() utc := t.In(time.UTC) fmt.Println("UTC 时间:", utc) loc, _ := time.LoadLocation("America/New_York") ny := t.In(loc) fmt.Println("纽约时间:", ny)
t.Local() Time
转换为本地时间。
- 示例
t := time.Now().UTC() local := t.Local() fmt.Println("本地时间:", local)
t.UTC() Time
转换为 UTC 时间。
- 示例
t := time.Now() utc := t.UTC() fmt.Println("UTC 时间:", utc)
t.IsZero() bool
判断时间是否为零值(0001-01-01 00:00:00 +0000 UTC)。
- 示例
var t time.Time fmt.Println("是否零值:", t.IsZero()) t2 := time.Now() fmt.Println("是否零值:", t2.IsZero())
判断两个时间是否相等(考虑时区)。
t.Equal(u Time) bool
- 示例
t1 := time.Date(2024, 1, 1, 12, 0, 0, 0, time.UTC) t2 := time.Date(2024, 1, 1, 20, 0, 0, 0, time.FixedZone("CST", 8*3600)) fmt.Println("是否相等:", t1.Equal(t2))
判断 t 是否在 u 之前。
t.Before(u Time) bool
- 示例
t1 := time.Now() t2 := t1.Add(time.Hour) fmt.Println("t1 在 t2 前:", t1.Before(t2))
判断 t 是否在 u 之后。
t.After(u Time) bool
- 示例
t1 := time.Now() t2 := t1.Add(-time.Hour) fmt.Println("t1 在 t2 后:", t1.After(t2))
比较两个时间。
t.Compare(u Time) int
- 说明:
- 返回 -1:t < u
- 返回 0:t == u
- 返回 1:t > u
- 示例
t1 := time.Now() t2 := t1.Add(time.Hour) fmt.Println("比较结果:", t1.Compare(t2))
计算时间差(t - u)。
t.Sub(u Time) Duration
- 示例
start := time.Now() time.Sleep(100 * time.Millisecond) elapsed := time.Now().Sub(start) fmt.Println("耗时:", elapsed)
加上一个持续时间。
t.Add(d Duration) Time
- 示例
t := time.Now() tomorrow := t.Add(24 * time.Hour) fmt.Println("明天:", tomorrow) anHourLater := t.Add(time.Hour) fmt.Println("1 小时后:", anHourLater)
加上年月日。
t.AddDate(years, months, days int) Time
- 示例
t := time.Now() nextYear := t.AddDate(1, 0, 0) fmt.Println("明年:", nextYear) nextMonth := t.AddDate(0, 1, 0) fmt.Println("下月:", nextMonth) tomorrow := t.AddDate(0, 0, 1) fmt.Println("明天:", tomorrow)
四舍五入到最接近的持续时间单位。
t.Round(d Duration) Time
- 示例
t := time.Date(2024, 0, 0, 12, 35, 30, 0, time.UTC) fmt.Println("四舍五入到分钟:", t.Round(time.Minute)) fmt.Println("四舍五入到小时:", t.Round(time.Hour))
截断到持续时间单位(向下取整)。
t.Truncate(d Duration) Time
- 示例
t := time.Date(2024, 0, 0, 12, 35, 30, 0, time.UTC) fmt.Println("截断到分钟:", t.Truncate(time.Minute)) fmt.Println("截断到小时:", t.Truncate(time.Hour))
返回时区名称和偏移量(秒)。
t.Zone() (name string, offset int)
- 示例
t := time.Now() name, offset := t.Zone() fmt.Printf("时区:%s, 偏移:%d 秒\n", name, offset)
返回当前时区的起止时间。
t.ZoneBounds() (start, end Time)
- 示例
t := time.Now() start, end := t.ZoneBounds() fmt.Println("时区开始:", start) fmt.Println("时区结束:", end)
⏱️ 持续时间类型(Duration)
time.Duration
表示两个时间点之间的时间间隔(纳秒)。
- 说明:
- 底层类型是 int64
- 单位是纳秒
- 可以转换为其他时间单位
- 常用常量:
- time.Nanosecond = 1(纳秒)
- time.Microsecond = 1000(微秒)
- time.Millisecond = 1000000(毫秒)
- time.Second = 1000000000(秒)
- time.Minute = 60 * Second(分钟)
- time.Hour = 60 * Minute(小时)
- 运算:
- 可以相加、相减
- 可以乘以数字
- 可以除以数字
- 示例
package main import ( "fmt" "time" ) func main() { // 使用常量 var d time.Duration = time.Second fmt.Println("1 秒:", d) // 计算 d2 := time.Minute + 30*time.Second fmt.Println("1 分 30 秒:", d2) // 转换 fmt.Println("毫秒:", d.Milliseconds()) fmt.Println("微秒:", d.Microseconds()) }
解析持续时间字符串。
time.ParseDuration(s string) (Duration, error)
- 说明:
- 支持单位:ns, us/µs, ms, s, m, h
- 可以组合使用,如 “1h30m20s”
- 示例(完整)
package main import ( "fmt" "time" ) func main() { d1, _ := time.ParseDuration("1h") fmt.Println("1 小时:", d1) d2, _ := time.ParseDuration("30m") fmt.Println("30 分钟:", d2) d3, _ := time.ParseDuration("1h30m20s") fmt.Println("组合:", d3) d4, _ := time.ParseDuration("100ms") fmt.Println("100 毫秒:", d4) }
返回持续时间的字符串表示。
d.String() string
- 示例
d := time.Hour + 30*time.Minute fmt.Println(d.String())
返回小时数。
d.Hours() float64
- 示例
d := 90 * time.Minute fmt.Println("小时数:", d.Hours())
返回分钟数。
d.Minutes() float64
- 示例
d := 2 * time.Hour fmt.Println("分钟数:", d.Minutes())
返回秒数。
d.Seconds() float64
- 示例
d := 1*time.Minute + 30*time.Second fmt.Println("秒数:", d.Seconds())
返回毫秒数。
d.Milliseconds() int64
- 示例
d := 5 * time.Second fmt.Println("毫秒数:", d.Milliseconds())
返回微秒数。
d.Microseconds() int64
- 示例
d := 5 * time.Millisecond fmt.Println("微秒数:", d.Microseconds())
返回纳秒数。
d.Nanoseconds() int64
- 示例
d := time.Millisecond fmt.Println("纳秒数:", d.Nanoseconds())
四舍五入到最接近的持续时间单位。
d.Round(m Duration) Duration
- 示例
d := 1*time.Minute + 35*time.Second fmt.Println(d.Round(time.Minute))
截断到持续时间单位。
d.Truncate(m Duration) Duration
- 示例
d := 1*time.Minute + 35*time.Second fmt.Println(d.Truncate(time.Minute))
返回绝对值。
d.Abs() Duration
- 示例
d := -5 * time.Second fmt.Println(d.Abs())
🔧 常用函数
计算从 t 到现在的时间间隔。
time.Since(t Time) Duration
- 说明:
- 等价于 time.Now().Sub(t)
- 常用于测量代码执行时间
- 示例(完整)
package main import ( "fmt" "time" ) func main() { start := time.Now() time.Sleep(100 * time.Millisecond) elapsed := time.Since(start) fmt.Println("执行时间:", elapsed) fmt.Println("毫秒数:", elapsed.Milliseconds()) }
计算从现在到 t 的时间间隔。
time.Until(t Time) Duration
- 说明:
- 等价于 t.Sub(time.Now())
- 常用于计算剩余时间
- 示例(完整)
package main import ( "fmt" "time" ) func main() { deadline := time.Now().Add(5 * time.Second) remaining := time.Until(deadline) fmt.Println("剩余时间:", remaining) time.Sleep(3 * time.Second) remaining = time.Until(deadline) fmt.Println("剩余时间:", remaining) }
暂停当前 goroutine 指定的时间。
time.Sleep(d Duration)
-
说明:
- 阻塞当前 goroutine 至少指定的时间
- 实际睡眠时间可能略长于指定时间
- 不会阻塞其他 goroutine
-
注意事项:
- 传入负数或零会立即返回
- 可以用 channel 或 context 提前唤醒
- 生产环境应使用 context.WithTimeout 控制超时
-
示例(完整)
package main import ( "fmt" "time" ) func main() { fmt.Println("开始") time.Sleep(2 * time.Second) fmt.Println("2 秒后") } -
使用场景示例
-
重试延迟
- 示例:
for i := 0; i < 3; i++ { if err := doSomething(); err != nil { time.Sleep(time.Second) // 等待 1 秒后重试 continue } break }
- 示例:
-
轮询
- 示例:
for { if checkStatus() { break } time.Sleep(500 * time.Millisecond) }
- 示例:
-
心跳检测
- 示例:
go func() { for { sendHeartbeat() time.Sleep(time.Minute) } }()
- 示例:
-
等待指定时间后发送当前时间。
time.After(d Duration) <-chan Time
- 说明:
- 返回一个 channel
- 常用于超时控制
- 示例(完整)
package main import ( "fmt" "time" ) func main() { fmt.Println("开始等待") t := <-time.After(2 * time.Second) fmt.Println("2 秒后:", t) }
周期性发送当前时间。
time.Tick(d Duration) <-chan Time
- 说明:
- 返回一个 ticker channel
- 无法停止(需要使用 time.NewTicker)
- 示例
package main import ( "fmt" "time" ) func main() { for t := range time.Tick(time.Second) { fmt.Println("每秒触发:", t) } }
🎯 Timer 和 Ticker
创建一次性定时器。
time.NewTimer(d Duration) *time.Timer
- 说明:
- 返回 Timer 对象
- 可以通过 C 通道接收时间
- 可以停止或重置
- 示例(完整)
package main import ( "fmt" "time" ) func main() { timer := time.NewTimer(2 * time.Second) go func() { <-timer.C fmt.Println("定时器触发") }() time.Sleep(3 * time.Second) }
在指定时间后执行函数。
time.AfterFunc(d Duration, f func()) *time.Timer
- 示例(完整)
package main import ( "fmt" "time" ) func main() { time.AfterFunc(2*time.Second, func() { fmt.Println("2 秒后执行") }) time.Sleep(3 * time.Second) }
停止定时器。
t.Stop() bool
- 说明:
- 返回 true:成功停止
- 返回 false:已触发或已停止
- 示例
timer := time.NewTimer(time.Hour) stopped := timer.Stop() fmt.Println("是否停止:", stopped)
重置定时器。
t.Reset(d Duration) bool
- 说明:
- 必须在定时器未触发时使用
- 返回是否成功
- 示例
timer := time.NewTimer(time.Second) timer.Reset(500 * time.Millisecond)
创建周期性定时器。
time.NewTicker(d Duration) *time.Ticker
- 说明:
- 返回 Ticker 对象
- 通过 C 通道周期性接收时间
- 需要手动调用 Stop() 停止
- 示例(完整)
package main import ( "fmt" "time" ) func main() { ticker := time.NewTicker(500 * time.Millisecond) defer ticker.Stop() done := make(chan bool) go func() { for { select { case t := <-ticker.C: fmt.Println("触发:", t) case <-done: return } } }() time.Sleep(2 * time.Second) done <- true }
停止 Ticker。
t.Stop()
- 示例
ticker := time.NewTicker(time.Second) defer ticker.Stop()
🌍 时区类型(Location)
*time.UTC Location
UTC 时区。
- 示例
t := time.Now().In(time.UTC) fmt.Println("UTC:", t)
*time.Local Location
本地时区。
- 示例
t := time.Now().In(time.Local) fmt.Println("本地:", t)
创建固定偏移量的时区。
time.FixedZone(name string, offset int) *Location
- 说明:
- offset: 秒数(东八区为 8*3600)
- 示例
cst := time.FixedZone("CST", 8*3600) t := time.Date(2024, 1, 1, 12, 0, 0, 0, cst) fmt.Println("东八区:", t)
加载指定时区。
time.LoadLocation(name string) (*Location, error)
- 说明:
- name: 如 “Asia/Shanghai”, “America/New_York”
- 示例(完整)
package main import ( "fmt" "time" ) func main() { loc, err := time.LoadLocation("Asia/Shanghai") if err != nil { fmt.Println("加载失败:", err) return } t := time.Now().In(loc) fmt.Println("上海时间:", t) ny, _ := time.LoadLocation("America/New_York") fmt.Println("纽约时间:", time.Now().In(ny)) }
*time.KnownDatacenter Location
已知的数据中心时区(已废弃)。
l.String() string
返回时区名称。
- 示例
loc := time.Local fmt.Println("时区名:", loc.String())
📆 月份和星期常量
time.Month
月份类型(1-12)。
- 常量:
- time.January = 1
- time.February = 2
- time.March = 3
- time.April = 4
- time.May = 5
- time.June = 6
- time.July = 7
- time.August = 8
- time.September = 9
- time.October = 10
- time.November = 11
- time.December = 12
- 示例
fmt.Println(time.January) fmt.Println(int(time.January))
返回月份字符串。
m.String() string
- 示例
m := time.March fmt.Println(m.String())
time.Weekday
星期类型(0-6)。
- 常量:
- time.Sunday = 0
- time.Monday = 1
- time.Tuesday = 2
- time.Wednesday = 3
- time.Thursday = 4
- time.Friday = 5
- time.Saturday = 6
- 示例
fmt.Println(time.Monday) fmt.Println(int(time.Monday))
返回星期字符串。
d.String() string
- 示例
d := time.Friday fmt.Println(d.String())
⏰ 预定义布局常量
标准布局:Mon Jan 2 15:04:05 MST 2006
time.Layout
- 示例
t := time.Now() fmt.Println(t.Format(time.Layout))
ANSIC 布局:Mon Jan 2 15:04:05 2006
time.ANSIC
- 示例
t := time.Now() fmt.Println(t.Format(time.ANSIC))
Unix 日期布局:Mon Jan 2 15:04:05 MST 2006
time.UnixDate
- 示例
t := time.Now() fmt.Println(t.Format(time.UnixDate))
Ruby 日期布局:Mon Jan 02 15:04:05 -0700 2006
time.RubyDate
- 示例
t := time.Now() fmt.Println(t.Format(time.RubyDate))
RFC822 布局:02 Jan 06 15:04 MST
time.RFC822
- 示例
t := time.Now() fmt.Println(t.Format(time.RFC822))
RFC822Z 布局:02 Jan 06 15:04 -0700
time.RFC822Z
- 示例
t := time.Now() fmt.Println(t.Format(time.RFC822Z))
RFC850 布局:Monday, 02-Jan-06 15:04:05 MST
time.RFC850
- 示例
t := time.Now() fmt.Println(t.Format(time.RFC850))
RFC1123 布局:Mon, 02 Jan 2006 15:04:05 MST
time.RFC1123
- 示例
t := time.Now() fmt.Println(t.Format(time.RFC1123))
RFC1123Z 布局:Mon, 02 Jan 2006 15:04:05 -0700
time.RFC1123Z
- 示例
t := time.Now() fmt.Println(t.Format(time.RFC1123Z))
RFC3339 布局:2006-01-02T15:04:05Z07:00
time.RFC3339
- 示例
t := time.Now() fmt.Println(t.Format(time.RFC3339))
RFC3339Nano 布局:2006-01-02T15:04:05.999999999Z07:00
time.RFC3339Nano
- 示例
t := time.Now() fmt.Println(t.Format(time.RFC3339Nano))
Kitchen 布局:3:04PM
time.Kitchen
- 示例
t := time.Now() fmt.Println(t.Format(time.Kitchen))
Stamp 布局:Jan 2 15:04:05
time.Stamp
- 示例
t := time.Now() fmt.Println(t.Format(time.Stamp))
StampMilli 布局:Jan 2 15:04:05.999
time.StampMilli
- 示例
t := time.Now() fmt.Println(t.Format(time.StampMilli))
StampMicro 布局:Jan 2 15:04:05.999999
time.StampMicro
- 示例
t := time.Now() fmt.Println(t.Format(time.StampMicro))
StampNano 布局:Jan 2 15:04:05.999999999
time.StampNano
- 示例
t := time.Now() fmt.Println(t.Format(time.StampNano))
🔍 时间比较和验证
判断两个时间是否相等。
time.Equal(t1, t2 Time) bool
- 示例
t1 := time.Now() t2 := t1 fmt.Println("是否相等:", t1.Equal(t2))
判断 t1 是否在 t2 之前。
time.Before(t1, t2 Time) bool
- 示例
t1 := time.Now() t2 := t1.Add(time.Hour) fmt.Println("t1 在 t2 前:", t1.Before(t2))
判断 t1 是否在 t2 之后。
time.After(t1, t2 Time) bool
- 示例
t1 := time.Now() t2 := t1.Add(-time.Hour) fmt.Println("t1 在 t2 后:", t1.After(t2))
比较两个时间。
time.Compare(t1, t2 Time) int
- 说明:
- 返回 -1:t1 < t2
- 返回 0:t1 == t2
- 返回 1:t1 > t2
- 示例
t1 := time.Now() t2 := t1.Add(time.Hour) fmt.Println("比较结果:", time.Compare(t1, t2))
📊 总结
时间类型
- Now 📍 获取当前时间
- Date 📅 创建指定日期
- Unix ⏱️ Unix 时间戳创建
- Parse 🔍 解析时间字符串
- ParseInLocation 🌍 指定时区解析
Time 方法
- Year/Month/Day 📆 获取日期组件
- Hour/Minute/Second ⏰ 获取时间组件
- Weekday/YearDay 📆 获取星期和年第几天
- Format 📝 格式化时间
- Unix/UnixNano ⏱️ 转换为时间戳
- In/Local/UTC 🌍 时区转换
- Add/AddDate ➕ 时间加法
- Sub ➖ 时间减法
- Before/After/Equal 🔍 时间比较
- Round/Truncate 🎯 四舍五入和截断
持续时间
- ParseDuration 🔍 解析持续时间
- Hours/Minutes/Seconds 📊 单位转换
- Milliseconds/Microseconds/Nanoseconds 📊 精确单位
- Round/Truncate 🎯 舍入操作
常用函数
- Since ⏱️ 计算经过时间
- Until ⏱️ 计算剩余时间
- Sleep 😴 暂停执行
- After ⏰ 延时触发
定时器
- NewTimer ⏰ 一次性定时器
- AfterFunc ⏰ 延时执行函数
- NewTicker 🔁 周期性定时器
- Stop/Reset 🛑 停止和重置
时区
- UTC/Local 🌍 标准时区
- FixedZone 🌍 固定偏移时区
- LoadLocation 🌍 加载时区数据库
预定义布局
- RFC3339/RFC3339Nano 📝 标准格式
- Kitchen/Stamp 📝 常用格式
- ANSIC/UnixDate 📝 传统格式
🎯 实用示例
测量代码执行时间
package main
import (
"fmt"
"time"
)
func main() {
start := time.Now()
// 模拟操作
time.Sleep(100 * time.Millisecond)
elapsed := time.Since(start)
fmt.Printf("执行时间:%v (%d 毫秒)\n", elapsed, elapsed.Milliseconds())
}
超时控制
package main
import (
"fmt"
"time"
)
func main() {
done := make(chan bool)
go func() {
time.Sleep(2 * time.Second)
done <- true
}()
select {
case <-done:
fmt.Println("操作完成")
case <-time.After(3 * time.Second):
fmt.Println("超时")
}
}
周期性任务
package main
import (
"fmt"
"time"
)
func main() {
ticker := time.NewTicker(time.Second)
defer ticker.Stop()
for i := 0; i < 5; i++ {
<-ticker.C
fmt.Println("第", i+1, "次触发:", time.Now().Format("15:04:05"))
}
}
时区转换
package main
import (
"fmt"
"time"
)
func main() {
now := time.Now()
utc := now.UTC()
fmt.Println("UTC 时间:", utc.Format(time.RFC3339))
loc, _ := time.LoadLocation("America/New_York")
ny := now.In(loc)
fmt.Println("纽约时间:", ny.Format(time.RFC3339))
loc, _ = time.LoadLocation("Europe/London")
london := now.In(loc)
fmt.Println("伦敦时间:", london.Format(time.RFC3339))
}
倒计时
package main
import (
"fmt"
"time"
)
func main() {
deadline := time.Now().Add(10 * time.Second)
ticker := time.NewTicker(time.Second)
defer ticker.Stop()
for range ticker.C {
remaining := time.Until(deadline)
if remaining <= 0 {
fmt.Println("时间到!")
break
}
fmt.Printf("剩余时间:%d 秒\n", int(remaining.Seconds()))
}
}
格式化输出
package main
import (
"fmt"
"time"
)
func main() {
t := time.Now()
fmt.Println("标准格式:", t.Format("2006-01-02 15:04:05"))
fmt.Println("RFC3339:", t.Format(time.RFC3339))
fmt.Println("日期:", t.Format("2006/01/02"))
fmt.Println("时间:", t.Format("15:04:05"))
fmt.Println("12 小时制:", t.Format("03:04:05 PM"))
fmt.Println("完整:", t.Format("2006-01-02 15:04:05.999999999 -0700 MST"))
}
时间计算
package main
import (
"fmt"
"time"
)
func main() {
now := time.Now()
tomorrow := now.AddDate(0, 0, 1)
fmt.Println("明天:", tomorrow.Format("2006-01-02"))
nextWeek := now.AddDate(0, 0, 7)
fmt.Println("下周:", nextWeek.Format("2006-01-02"))
nextMonth := now.AddDate(0, 1, 0)
fmt.Println("下月:", nextMonth.Format("2006-01-02"))
nextYear := now.AddDate(1, 0, 0)
fmt.Println("明年:", nextYear.Format("2006-01-02"))
hourAgo := now.Add(-time.Hour)
fmt.Println("1 小时前:", hourAgo.Format("15:04:05"))
}
解析时间字符串
package main
import (
"fmt"
"time"
)
func main() {
layouts := []string{
"2006-01-02",
"2006-01-02 15:04:05",
"2006/01/02",
"02-Jan-2006",
time.RFC3339,
}
values := []string{
"2024-03-15",
"2024-03-15 10:30:00",
"2024/03/15",
"15-Mar-2024",
"2024-03-15T10:30:00Z",
}
for i, layout := range layouts {
t, err := time.Parse(layout, values[i])
if err != nil {
fmt.Printf("解析失败:%v\n", err)
continue
}
fmt.Printf("解析成功:%v\n", t.Format("2006-01-02 15:04:05"))
}
}
定时器管理
package main
import (
"fmt"
"time"
)
func main() {
timer := time.NewTimer(2 * time.Second)
go func() {
<-timer.C
fmt.Println("定时器触发")
}()
time.Sleep(1 * time.Second)
stopped := timer.Stop()
fmt.Println("是否成功停止:", stopped)
timer.Reset(1 * time.Second)
time.Sleep(2 * time.Second)
}
性能分析
package main
import (
"fmt"
"time"
)
func main() {
start := time.Now()
defer func() {
elapsed := time.Since(start)
fmt.Printf("函数执行时间:%v\n", elapsed)
}()
time.Sleep(100 * time.Millisecond)
}