Golang将time.Time转换为Unix时间戳时会添加额外的小时。

huangapple go评论87阅读模式
英文:

golang converting time.Time to unix adds extra hours

问题

我遇到了一个问题。
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中的数据类型更改为带有时区的时间戳,但转换仍然会添加额外的小时数。

英文:

I ran into a problem.
The PostgreSQL database stores the date and time in the format "timestamp without time zone".
If you get the date and time from the database and try to convert it to seconds it adds 4 extra hours
Example:

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

What are some ways to fix this or convert the date and time seconds more correctly?

I tried changing the data type in postgres to timestamp with time zone but the conversion also adds extra hours

答案1

得分: 3

文档:

时间包

func Unix(sec int64, nsec int64) Time

Unix函数返回与给定的Unix时间相对应的本地时间,即自1970年1月1日UTC起的sec秒和nsec纳秒。

如预期,你得到了本地时间:2023-05-21 04:00:00 +0400。你想要的是UTC时间。


package main

import (
	"fmt"
	"time"
)

func main() {
	at, err := time.Parse("2006-01-02", "2023-05-21")
	fmt.Println(at, err)
	// 得到
	local := time.Unix(at.Unix(), 0)
	fmt.Println(local)
	// 想要
	utc := time.Unix(at.Unix(), 0).UTC()
	fmt.Println(utc)
}

美国东部夏令时(EDT)的本地时间:

2023-05-21 00:00:00 +0000 UTC <nil>
2023-05-20 20:00:00 -0400 EDT
2023-05-21 00:00:00 +0000 UTC
英文:

The documentation:

> Package time
>
> func Unix(sec int64, nsec int64) Time
>
> Unix returns the local Time corresponding to the given Unix time, sec seconds and nsec nanoseconds since January 1, 1970 UTC.

As expected, you got your local time: 2023-05-21 04:00:00 +0400. You want UTC time.


package main

import (
	&quot;fmt&quot;
	&quot;time&quot;
)

func main() {
	at, err := time.Parse(&quot;2006-01-02&quot;, &quot;2023-05-21&quot;)
	fmt.Println(at, err)
	// got
	local := time.Unix(at.Unix(), 0)
	fmt.Println(local)
	// want
	utc := time.Unix(at.Unix(), 0).UTC()
	fmt.Println(utc)
}

Local US Eastern Daylight Saving Time (EDT):

2023-05-21 00:00:00 +0000 UTC &lt;nil&gt;
2023-05-20 20:00:00 -0400 EDT
2023-05-21 00:00:00 +0000 UTC

答案2

得分: 0

我可以这样解决这个问题:

tm := time.Date(
    menu.OpeningRecordAt.Year(),
    menu.OpeningRecordAt.Month(),
    menu.OpeningRecordAt.Day(),
    menu.OpeningRecordAt.Hour(),
    menu.OpeningRecordAt.Minute(),
    menu.OpeningRecordAt.Second(),
    menu.OpeningRecordAt.Nanosecond(),
    time.Local,
)

有更好的选择吗?

英文:

I was able to solve the problem this way

tm := time.Date(
	menu.OpeningRecordAt.Year(),
	menu.OpeningRecordAt.Month(),
	menu.OpeningRecordAt.Day(),
	menu.OpeningRecordAt.Hour(),
	menu.OpeningRecordAt.Minute(),
	menu.OpeningRecordAt.Second(),
	menu.OpeningRecordAt.Nanosecond(),
	time.Local,
)

is there a better option?

huangapple
  • 本文由 发表于 2023年5月21日 06:28:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/76297576.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定