Go语言时间转换问题排查:附代码示例
Go语言时间转换问题排查与代码解析
嘿,我帮你捋捋这段处理时间转换的Go代码,顺便揪出那些容易踩的坑~先把完整代码贴出来:
package main import ( "fmt" "time" ) func unix2Str(ts int64) string { const layout = "20060102" t := time.Unix(ts, 0) return t.Format(layout) } func unixTime(ts string) int64 { const layout = "20060102" t, err := time.Parse(layout, ts) if err != nil { fmt.Println(err) return 0 } return t.Unix() } func main() { ts1 := "20110320" ts2 := "20110321" ut1 := unixTime(ts1) ut2 := unixTime(ts2) fmt.Println(ts1, "对应的时间戳:", ut1) fmt.Println(ts2, "对应的时间戳:", ut2) fmt.Println(ut1, "转日期:", unix2Str(ut1)) }
核心函数拆解
1. unix2Str:Unix时间戳转日期字符串
这个函数逻辑很直接:把Unix时间戳转成time.Time对象,再格式化为YYYYMMDD的字符串。但这里有个隐形的坑——time.Unix默认用本地时区生成时间。如果你的服务部署在不同时区的服务器上,比如本地是东八区,服务器在UTC时区,转换出来的日期可能会差一天!
2. unixTime:日期字符串转Unix时间戳
同样的问题,time.Parse默认也是用本地时区解析日期。举个例子:如果输入的"20110320"是UTC的0点,但你的本地是东八区,解析出来的时间就是2011-03-20 00:00:00 +0800 CST,对应的Unix时间戳会比UTC时区的0点少8小时,这就会导致后续转换出问题。
常见问题修复方案
强制统一时区(推荐用UTC)
如果你的业务需要跨时区兼容,统一用UTC绝对是最稳妥的选择。修改两个函数如下:
// Unix时间戳转UTC日期字符串 func unix2Str(ts int64) string { const layout = "20060102" // 明确转成UTC时区 t := time.Unix(ts, 0).UTC() return t.Format(layout) } // 日期字符串转UTC时间戳 func unixTime(ts string) (int64, error) { const layout = "20060102" // 加载UTC时区 loc, err := time.LoadLocation("UTC") if err != nil { return 0, err } // 用指定时区解析 t, err := time.ParseInLocation(layout, ts, loc) if err != nil { return 0, err } return t.Unix(), nil }
优化错误处理
原代码里unixTime在解析失败时直接返回0,这其实不太友好——调用方可能分不清是解析错误还是真的对应时间戳0。改成返回(int64, error)的形式,让调用方自己处理异常,会更健壮。
测试验证
修改后的main函数可以这么写,验证转换是否符合预期:
func main() { ts1 := "20110320" ts2 := "20110321" ut1, err := unixTime(ts1) if err != nil { fmt.Println("解析ts1出错:", err) return } ut2, err := unixTime(ts2) if err != nil { fmt.Println("解析ts2出错:", err) return } fmt.Printf("%s 对应的UTC时间戳:%d\n", ts1, ut1) fmt.Printf("%s 对应的UTC时间戳:%d\n", ts2, ut2) fmt.Printf("%d 转UTC日期:%s\n", ut1, unix2Str(ut1)) }
这样不管你的代码跑在哪个时区,转换结果都是一致的,不会出现跨时区的偏差问题。
内容的提问来源于stack exchange,提问作者Valentin
相关产品推荐
相关产品推荐

