Golang中time.Time转换为Unix时间戳时出现额外小时数的问题
Golang中time.Time转换为Unix时间戳时出现额外小时数的问题 我遇到了一个问题。PostgreSQL数据库以“不带时区的时间戳”格式存储日期和时间。如果从数据库获取日期和时间并尝试将其转换为秒,它会额外增加4个小时。示例:
fmt.Println(menu.OpeningRecordAt, "|", time.Unix(menu.OpeningRecordAt.Unix(), 0))
// 2023-05-21 00:00:00 +0000 UTC | 2023-05-21 04:00:00 +0400 +04
有哪些方法可以修复这个问题,或者更正确地转换日期和时间秒数?
我尝试将PostgreSQL中的数据类型更改为带时区的时间戳,但转换仍然会额外增加小时数。
更多关于Golang中time.Time转换为Unix时间戳时出现额外小时数的问题的实战教程也可以访问 https://www.itying.com/category-94-b0.html
这些是相同的时间戳。一个是UTC时间,另一个是本地时间(在你的例子中是+0400)。如果你将时间戳存储为UTC,那么加上4小时来获取本地时间是正确的。
更多关于Golang中time.Time转换为Unix时间戳时出现额外小时数的问题的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
补充一下上面 @Dean_Davidson 所说的……在右边的那个加上 .UTC(),或者在左边的那个加上 .Local()。
PS:如果可能的话,处理时间时请始终使用 UTC。
问题在于Go的time.Time类型包含时区信息,而PostgreSQL的"不带时区的时间戳"在解析时会默认使用UTC时区。当您调用Unix()方法时,返回的是UTC时间的Unix时间戳,但用time.Unix()重新构造时间时,会使用系统的本地时区。
以下是几种解决方案:
方案1:使用UTC时间统一处理
// 将时间转换为UTC时区后再获取Unix时间戳
unixTime := menu.OpeningRecordAt.UTC().Unix()
fmt.Println(unixTime)
// 重新构造时也使用UTC
reconstructed := time.Unix(unixTime, 0).UTC()
fmt.Println(reconstructed)
方案2:在数据库查询时处理时区
// 在SQL查询中使用AT TIME ZONE
query := `SELECT opening_record_at AT TIME ZONE 'UTC' FROM menus`
// 或者使用您本地的时区
query := `SELECT opening_record_at AT TIME ZONE 'Asia/Tbilisi' FROM menus`
方案3:使用time.Time的In方法指定时区
// 明确指定时区
location, _ := time.LoadLocation("Asia/Tbilisi") // 根据您的时区调整
localTime := menu.OpeningRecordAt.In(location)
fmt.Println(localTime.Unix())
// 或者始终使用UTC
utcTime := menu.OpeningRecordAt.In(time.UTC)
fmt.Println(utcTime.Unix())
方案4:检查数据库连接时区设置
// 在数据库连接字符串中指定时区
connStr := "host=localhost user=postgres dbname=test sslmode=disable TimeZone=Asia/Tbilisi"
关键点:
- PostgreSQL的"timestamp without time zone"不存储时区信息,Go驱动程序会将其解析为UTC时间
Unix()方法返回的是UTC时间的秒数time.Unix()使用本地时区构造时间对象
建议在应用程序中统一使用UTC时间进行处理,只在显示时转换为本地时区。这样可以避免时区转换带来的混乱。


