go中time.time变量声明即初始化为零值(公元1年1月1日00:00:00 utc),不可为nil;常用初始化方式包括var t time.time、t := time.now()、time.parse()或time.date()。

Go里time.Time变量怎么声明和初始化
直接用time.Time类型声明,但必须初始化,否则是零值(1年1月1日0时0分0秒 UTC),不是nil——这点容易误判为“空时间”。
- 声明并赋零值:
var t time.Time,此时t等于time.Time{} - 声明并初始化为当前时间:
t := time.Now()或t = time.Now() - 解析字符串得时间:
t, err := time.Parse("2006-01-02", "2024-05-20"),注意布局字符串必须是Go固定格式"2006-01-02",不是任意占位符 - 构造特定时间(UTC):
t := time.Date(2024, 5, 20, 10, 30, 0, 0, time.UTC),月份用time.Month常量更安全(如time.May)
Go里time.Duration变量怎么声明和赋值
time.Duration本质是int64,单位是纳秒,但写代码时绝不用裸数字,必须用预定义常量组合,否则可读性差且易出错。
- 正确写法:
d := 5 * time.Second、d := 30 * time.Minute、d := time.Hour + 30*time.Minute - 错误写法:
d := 300(单位不明)、d := 5 * 1e9(绕过类型检查,失去语义) - 从字符串解析时用
time.ParseDuration("2h30m"),支持"1.5h"、"30s"等,但不支持中文或空格分隔 - 注意:
time.Duration不能直接和int运算,5 + time.Second会编译报错
time.Time和time.Duration混用的常见坑
两者类型不同,不能直接加减,但time.Time支持+ Duration和- Duration,反过来Duration + Time非法。
- 合法:
later := t.Add(2 * time.Hour)、earlier := t.Add(-30 * time.Minute)、diff := t2.Sub(t1)(返回time.Duration) - 非法:
t := 2 * time.Hour + t1(顺序反了)、t1 - t2(只能用Sub) - 比较时间用
Before/After/Equal方法,别用==——因为time.Time包含位置信息,两个相同时刻但不同时区的值==返回false - 如果需要忽略时区做比较,先转成UTC:
t1.UTC().Equal(t2.UTC())
为什么不能用struct{}或指针模拟“可空时间”
很多人想表达“未设置时间”,试图用*time.Time或struct{ t time.Time; valid bool },但这增加了复杂度,且Go标准库所有API都基于非空time.Time设计。
- 推荐做法:用零值
time.Time{}表示“未设置”,并在业务逻辑中显式判断t.IsZero()(它专为此设计) - 避免
new(time.Time)或&time.Time{}——虽然能编译,但零值本身已足够表达“无意义时间” - JSON序列化时,零值默认输出
"0001-01-01T00:00:00Z",如需隐藏,得自定义MarshalJSON方法
真正麻烦的不是声明语法,而是理解time.Time自带时区、精度、零值语义这三层隐含约束;哪怕只漏掉IsZero()检查,就可能让定时任务提前一千年触发。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











