如何将时区设置为现有时间戳而不重新解释它?

jbr*_*own 3 timezone go

我正在解析用户发送的时间戳。时间戳是某个位置的本地时间戳,但源字符串未指定它。在服务器端,我正在查找该位置的时区,并且需要将时间转移到该时区,而不更改其显示值。

我知道我可以这样做,以便在不同的地点给我同等的时间:

package main

import (
    "fmt"
    "time"
)

func main() {
    myTime := time.Now()
    fmt.Println(myTime.Format(time.RFC3339))
    
    loc, err := time.LoadLocation("America/New_York")
    if err != nil {
        panic(err)
    }
    
    fmt.Println(myTime.In(loc).Format(time.RFC3339))
}

Run Code Online (Sandbox Code Playgroud)

这只是打印:

2009-11-10T23:00:00Z
2009-11-10T18:00:00-05:00
Run Code Online (Sandbox Code Playgroud)

这不是我想要的。

我正在尝试找到一种将时区设置为 eg 的方法America/New_York,所以我应该得到 eg 2009-11-10T23:00:00-05:00,这是原始的当地时间,但应用了纽约偏移量。

我怎样才能在 Go 中做到这一点?

bla*_*een 5

令人困惑的原因是,直观地浮现在脑海中的 APIIn简单地解释了同一时间点,就好像它位于不同的时区一样。所以当你打印它时,显示的效果并不是你想要的。

要将时区设置为时间戳,同时保持相同的显示值,您可以简单地使用与time.Date原始时间戳和新位置相同的值构造新时间戳:

t := time.Date(myTime.Year(), myTime.Month(), myTime.Day(), myTime.Hour(), myTime.Minute(), myTime.Second(), myTime.Nanosecond(), loc)
// 2009-11-10T23:00:00-05:00 in the playground
Run Code Online (Sandbox Code Playgroud)

另一种选择是将时间实例设置为新时区,然后使用Zone()获取偏移量,然后从本地时间中减去其以秒为单位的值。

package main

import (
    "fmt"
    "time"
)

func main() {
    myTime := time.Now()
    fmt.Println(myTime.Format(time.RFC3339))
    
    loc, err := time.LoadLocation("America/New_York")
    if err != nil {
        panic(err)
    }

    locTime := myTime.In(loc)
    _, zoneOffset := locTime.Zone()
    
    inZoneTime := locTime.Add(-time.Duration(zoneOffset) * time.Second)

    // handle DST transitions
    if inZoneTime.IsDST() {
        inZoneTime = inZoneTime.Add(1*time.Hour)
    }
    
    fmt.Println(inZoneTime.Format(time.RFC3339))
    // 2009-11-10T23:00:00-05:00
}
Run Code Online (Sandbox Code Playgroud)

今天要在本地计算机上测试 DST 转换(假设您位于非 DST 国家/地区,就像我一样),您可以将位置更改为 DST 处于活动状态的位置,例如Australia/Canberra

当输入time.Now()without DST 到 时Australia/Canberra,上面的程序会打印以下内容:

2021-11-12T13:27:33+01:00
is DST: true
2021-11-12T13:27:33+11:00
Run Code Online (Sandbox Code Playgroud)

游乐场: https: //play.golang.org/p/5qy2tOcIMwn