Go 中 time.Parse() 的1个坑

发布时间 2023-10-26 16:45:53作者: 技术颜良

Go 中 time.Parse() 的1个坑

time.Parse()

time.Parse()要慎用,Parse出来的是UTC时间,尽量用time.ParseInLocation()得到CST时间,因为我们通过time.Now()获取的都是CST时间,如果用time.Before()或者time.After()来比较两者,可能会出现预期外的比较结果。例子:

package main

import (
    "log"
    "time"
)

func main() {
    now := time.Now()
    log.Printf("now: %v", now)

    todayZero, _ := time.Parse("20060102", now.Format("20060102"))
    log.Printf("todayZero: %v", todayZero)

    // 当日0点30
    beginTime := todayZero.Add(30 * time.Minute)
    log.Printf("beginTime: %v", beginTime)

    // 当日4点
    endTime := todayZero.Add(4 * time.Hour)
    log.Printf("endTime: %v", endTime)

    // 假设此时为北京时间10:00,则会导致输出true,但实际并不符合预期
    if now.After(beginTime) && now.Before(endTime) {
        log.Printf("true")
    } else {
        log.Printf("false")
    }
}

如果没有指定时区,Parse 方法以UTC返回时间

UTC是什么?

整个地球分为二十四时区,每个时区都有自己的本地时间。在国际无线电通信场合,使用一个统一的时间,称为通用协调时(UTC, Universal Time Coordinated)。UTC与格林尼治平均时(GMT, Greenwich Mean Time)一样,都与英国伦敦的本地时相同。北京时区是东八区,领先UTC八个小时。

UTC + 时区差 = 本地时间

举个例子看下面的代码

func main() {
 now := time.Now()
 st := now.Format("2006-01-02 15:04:05")
 fmt.Printf("%s\n", st)

 fmt.Println(now.Unix())
 
 t, _ := time.Parse("2006-01-02 15:04:05", st)
 fmt.Println(t.Unix())

 tt := time.Unix(t.Unix(), 0)
 fmt.Println(tt.Format("2006-01-02 15:04:05"))
}

执行结果:

2023-08-13 21:17:52
1691932672
1691961472
2023-08-14 05:17:52

可以看到,当前时间比 UTC 时间晚 8小时

要解决这个问题,需要使用 ParseInLocation 方法设置时区:

var LOC, _ = time.LoadLocation("Asia/Shanghai")
t, _ := time.ParseInLocation("2006-01-02 15:04:05", st, LOC)

 

获更多内容,关注公众号程序员奇点

图片公众号:程序员奇点博客:CSDN 王小明关注我们,了解更多

关注后:回复 “idea” 或者 “内推”或者“书籍”, 有惊喜

 

 

程序员奇点
分享 读书,旅行,摄影,IT技术,欢迎积极讨论
277篇原创内容

 

猿星人
收录于合集 #技术
 8
上一篇TCP:三次握手|4次挥手下一篇国内访问 GitHub 加速器
 
阅读 531
程序员奇点