(编辑/更新):感谢@djd指出我们可以跳过所有JSON / struct解码业务;关键问题在于time.Parse
。
同样的问题出现在这里,Location
是“空”而不是UTC(我希望UTC基于文档:https://golang.org/pkg/time/#Parse
“如果没有时区指示符,Parse将返回UTC时间。”
以下是示例代码:https://play.golang.org/p/pb3eMbjSmv
package main
import (
"fmt"
"time"
)
func main() {
// Ignoring the err just for this example's sake!
parsed, _ := time.Parse(time.RFC3339, "2017-08-15T22:30:00+00:00")
fmt.Printf("String(): %v\n", parsed.String())
fmt.Printf("Location(): %v\n", parsed.Location())
}
输出
String(): 2017-08-15 22:30:00 +0000 +0000
Location():
因此,虽然time.Time
的{{1}}的偏移量似乎是正确的,但其时区名称只是一个空字符串。在其他机器(和The Go Playground)上运行会给出预期的“UTC”位置。
[原帖]:
在我的本地OS X计算机上将时间戳字段从JSON解码为Location
时,struct
字段的Location
为“空”而不是UTC。这对我在本地运行单元测试是有问题的(在time.Time
正确设置为UTC的CI服务器上。)
当我在我的机器上运行时,我看到了
Location
因此,虽然go run main.go
TimeField.String(): 2017-08-15 22:30:00 +0000 +0000
TimeField.Location():
的{{1}}的偏移量似乎是正确的,但其时区名称只是一个空字符串。这是使用Go 1.5:
time.Time
答案 0 :(得分:0)
我在Mac上使用我当前的设置发现了相同的行为,我怀疑它在Linux上会有相同的行为(不确定)
$ go version
go version devel +31ad583 Wed Aug 10 19:44:08 2016 +0000 darwin/amd64
为了使其更具确定性,我建议使用自定义的json Unmarshal:
package main
import (
"encoding/json"
"fmt"
"strings"
"time"
)
type Time struct {
*time.Time
}
func (t *Time) UnmarshalJSON(b []byte) error {
const format = "\"2006-01-02T15:04:05+00:00\""
t_, err := time.Parse(format, string(b))
if err != nil {
return err
}
*t = Time{&t_}
return nil
}
type Example struct {
TimeField *Time `json:"time_field"`
}
func main() {
inString := "{\"time_field\": \"2017-08-15T22:30:00+00:00\"}"
var ex Example
decoder := json.NewDecoder(strings.NewReader(inString))
decoder.Decode(&ex)
fmt.Printf("TimeField.String(): %v\n", ex.TimeField.String())
fmt.Printf("TimeField.Location(): %v\n", ex.TimeField.Location())
}
答案 1 :(得分:0)
是的,你是对的。在The Go Playground中,Local
在该沙箱中设置为UTC
:
在 The Go Playground :
package main
import (
"fmt"
"runtime"
"time"
)
func main() {
fmt.Println(runtime.Version(), runtime.GOARCH, runtime.GOOS) //go1.7 amd64p32 nacl
parsed, err := time.Parse(time.RFC3339, "2017-08-15T22:30:00+00:00")
if err != nil {
panic(err)
}
fmt.Printf("String(): %v\n", parsed.String())
fmt.Printf("Location(): %v\n", parsed.Location())
}
The Go Playground上的输出:
go1.7 amd64p32 nacl
String(): 2017-08-15 22:30:00 +0000 UTC
Location(): UTC
在本地系统上尝试,输出Location()
为空。
您可以将utc := parsed.UTC()
的位置设置为UTC,例如此工作示例代码 The Go Playground :
package main
import (
"fmt"
"runtime"
"time"
)
func main() {
fmt.Println(runtime.Version(), runtime.GOARCH, runtime.GOOS) //go1.7 amd64p32 nacl
parsed, err := time.Parse(time.RFC3339, "2017-08-15T22:30:00+00:00")
if err != nil {
panic(err)
}
fmt.Printf("String(): %v\n", parsed.String())
fmt.Printf("Location(): %v\n", parsed.Location())
utc := parsed.UTC()
fmt.Printf("String(): %v\n", utc.String())
fmt.Printf("Location(): %v\n", utc.Location())
}
此外,您可以使用time.ParseInLocation(time.RFC3339, "2017-08-15T22:30:00+00:00", time.UTC)
,例如此工作示例代码:
package main
import (
"fmt"
"runtime"
"time"
)
func main() {
fmt.Println(runtime.Version(), runtime.GOARCH, runtime.GOOS) //go1.7 amd64p32 nacl
parsed, err := time.ParseInLocation(time.RFC3339, "2017-08-15T22:30:00+00:00", time.UTC)
if err != nil {
panic(err)
}
fmt.Printf("String(): %v\n", parsed.String())
fmt.Printf("Location(): %v\n", parsed.Location())
}
因此Location()
将为UTC
。
答案 2 :(得分:0)
感谢@djd指出我们可以跳过所有的JSON/struct解码业务;关键问题在于 time.Parse
。
这里出现了同样的问题,其中 Location
是“空”而不是 UTC(根据文档,我期望 UTC:https://golang.org/pkg/time/#Parse
在没有时区指示器的情况下,Parse 返回一个 UTC 时间。
此答案取自 revision 6 的问题。