好好爱自己!

【转】Golang中 time.Parse和time.Format的时区问题

原文:https://www.zhetenga.com/view/Golang%E4%B8%AD%20time.Parse%E5%92%8Ctime.Format%E7%9A%84%E6%97%B6%E5%8C%BA%E9%97%AE%E9%A2%98-674f19176.html

------------------------------------------

涉及到时间处理时,Parse 和 Format 是最为常见的处理了。

Parse:将字符串格式的时间转为 time.Time,类似 PHP 中的 strtotime;Format:将 time.Time 格式化为字符串格式的时间,类似 PHP 中的 timetostr。

提到时间,它一定需要跟时区一起才有意义,比如 15:30:00 这个时间,其实并不明确,因为你不知道这是北京时间还是东京时间。而一般人的理解里,如果没提到时区,就默认是当地的时区,比如我说 15:30:00,大家都能理解为下午三点,是因为同在北京时区里。

回到 time.Format,它返回的是固定的字符串,格式化时它是需要明确时区信息的,但 Format 函数却没有时区参数。事实上它的时区信息来源于 time.Time 结构体的 loc 字段,而并不允许作为参数传入。这也解释了为什么 time.Now().Format() 会返回当地时区的时间字符串,因为 time.Now() 返回的 time.Time 默认是当地时区。

type Time struct {

sec int64

nsec int32

loc *Location

}

总结起来就是:time.Format 的时区信息来源于 Time 结构体中的 loc,time.Now().Format() 返回的是当地时区的时间。

然后是 time.Parse,如果它的参数没有带入时区信息,比如没有 +0800 这样的信息,它将默认使用 UTC 时间,这意味着:

s := time.Now().Format("2006-01-02 15:04:05")

t, _ := time.Parse("2006-01-02 15:04:05", s)

上面的 s 和 t 已经完全不一样了,因为 s 返回的是当地时区,而 t 则变成了 UTC 时间。这也解释了为什么经过这么一个习惯性操作,得到的时间居然是不符合预期的了。

正确的做法是使用 ParseInLocation 来 Parse 明确是同一时间的不带时间信息的时间字符串:

s := time.Now().Format("2006-01-02 15:04:05")

t, _ := time.ParseInLocation("2006-01-02 15:04:05", s, time.Local)

这样做才会符合习惯于 strtotime 和 timetostr 的结果预期。

总结起来就是:如果时间字符串中带了时区信息才去使用 time.Parse,否则使用 time.ParseInLocation。

posted @   立志做一个好的程序员  阅读(2666)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
历史上的今天:
2019-07-30 gorm忽略struct种的field, 不映射到表里面
2019-07-30 golang 2 ways to delete an element from a slice
2019-07-30 Procomm Plus 与ASPECT脚本语言在基于远程终端设备上的测试应用
2018-07-30 ubuntu 的runlevel设定
2018-07-30 Ubuntu14.04配置nginx开机自启动项
2017-07-30 c语言char 和int的问题

不断学习创作,与自己快乐相处

点击右上角即可分享
微信分享提示