解组格式不正确的日期时间
Unmarshal incorrectly formatted datetime
背景
我正在学习 Go,我正在尝试对日期时间进行一些 JSON 解组处理。
我用 C 编写的程序生成了一些 JSON,我正在输出我认为有效的 ISO8601 / RFC3339 timezone offset. I'm using strftime
,格式字符串如下:
%Y-%m-%dT%H:%M:%S.%f%z
(请注意,strftime
本身不支持 %f
,我有一个用纳秒替换它的包装器)。
这将产生以下结果:
2016-08-08T21:35:14.052975+0200
然而,在 Go 中解组它是行不通的:
https://play.golang.org/p/vzOXbzAwdW
package main
import (
"fmt"
"time"
)
func main() {
t, err := time.Parse(time.RFC3339Nano, "2016-08-08T21:35:14.052975+0200")
if err != nil {
panic(err)
}
fmt.Println(t)
}
输出:
panic: parsing time "2016-08-08T21:35:14.052975+0200" as "2006-01-02T15:04:05.999999999Z07:00": cannot parse "+0200" as "Z07:00"
(工作示例:https://play.golang.org/p/5xcM0aHsSw)
这是因为 RFC3339 期望时区偏移量的格式为 02:00
和 :
,但 strftime
将其输出为0200
.
所以我需要在我的 C 程序中修复这个问题以输出正确的格式。
%z The +hhmm or -hhmm numeric timezone (that is, the hour and
minute offset from UTC). (SU)
问题
但是,现在我有一堆 JSON 格式不正确的文件:
2016-08-08T21:35:14.052975+0200
而不是正确的(在时区偏移中使用 :
):
2016-08-08T21:35:14.052975+02:00
但我仍然希望能够在我的 Go 程序中正确解组它。最好是两个不同的 JSON 文件,只有这个区别应该以完全相同的方式解析。
关于编组回 JSON,应使用正确的格式。
这是我在 struct
:
中定义的方式
Time time.Time `json:"time"`
所以问题是,执行此操作的“Go”方式是什么?
同样在我的代码示例中,我使用了 RFC3339Nano
。我将如何在结构的元数据中指定它?正如我现在拥有的那样 json:"time"
会忽略纳秒吗?
你可以试试https://play.golang.org/p/IsUpuTKENg
package main
import (
"fmt"
"time"
)
func main() {
t, err := time.Parse("2006-01-02T15:04:05.999999999Z0700", "2016-08-08T21:35:14.052975-0200")
if err != nil {
panic(err)
}
fmt.Println(t)
}
您可以定义自己的 time
支持两种格式的字段类型:
type MyTime struct {
time.Time
}
func (self *MyTime) UnmarshalJSON(b []byte) (err error) {
s := string(b)
// Get rid of the quotes "" around the value.
// A second option would be to include them
// in the date format string instead, like so below:
// time.Parse(`"`+time.RFC3339Nano+`"`, s)
s = s[1:len(s)-1]
t, err := time.Parse(time.RFC3339Nano, s)
if err != nil {
t, err = time.Parse("2006-01-02T15:04:05.999999999Z0700", s)
}
self.Time = t
return
}
type Test struct {
Time MyTime `json:"time"`
}
在上面的示例中,我们采用预定义格式 time.RFC3339Nano
,其定义如下:
RFC3339Nano = "2006-01-02T15:04:05.999999999Z07:00"
并删除 :
"2006-01-02T15:04:05.999999999Z0700"
这里描述了 time.Parse
使用的时间格式:
https://golang.org/pkg/time/#pkg-constants
另请参阅 time.Parse
的文档
https://golang.org/pkg/time/#Parse
P.S。时间格式字符串中使用年份 2006
可能是因为那一年发布了 Golang 的第一个版本。
背景
我正在学习 Go,我正在尝试对日期时间进行一些 JSON 解组处理。
我用 C 编写的程序生成了一些 JSON,我正在输出我认为有效的 ISO8601 / RFC3339 timezone offset. I'm using strftime
,格式字符串如下:
%Y-%m-%dT%H:%M:%S.%f%z
(请注意,strftime
本身不支持 %f
,我有一个用纳秒替换它的包装器)。
这将产生以下结果:
2016-08-08T21:35:14.052975+0200
然而,在 Go 中解组它是行不通的: https://play.golang.org/p/vzOXbzAwdW
package main
import (
"fmt"
"time"
)
func main() {
t, err := time.Parse(time.RFC3339Nano, "2016-08-08T21:35:14.052975+0200")
if err != nil {
panic(err)
}
fmt.Println(t)
}
输出:
panic: parsing time "2016-08-08T21:35:14.052975+0200" as "2006-01-02T15:04:05.999999999Z07:00": cannot parse "+0200" as "Z07:00"
(工作示例:https://play.golang.org/p/5xcM0aHsSw)
这是因为 RFC3339 期望时区偏移量的格式为 02:00
和 :
,但 strftime
将其输出为0200
.
所以我需要在我的 C 程序中修复这个问题以输出正确的格式。
%z The +hhmm or -hhmm numeric timezone (that is, the hour and
minute offset from UTC). (SU)
问题
但是,现在我有一堆 JSON 格式不正确的文件:
2016-08-08T21:35:14.052975+0200
而不是正确的(在时区偏移中使用 :
):
2016-08-08T21:35:14.052975+02:00
但我仍然希望能够在我的 Go 程序中正确解组它。最好是两个不同的 JSON 文件,只有这个区别应该以完全相同的方式解析。
关于编组回 JSON,应使用正确的格式。
这是我在 struct
:
Time time.Time `json:"time"`
所以问题是,执行此操作的“Go”方式是什么?
同样在我的代码示例中,我使用了 RFC3339Nano
。我将如何在结构的元数据中指定它?正如我现在拥有的那样 json:"time"
会忽略纳秒吗?
你可以试试https://play.golang.org/p/IsUpuTKENg
package main import ( "fmt" "time" ) func main() { t, err := time.Parse("2006-01-02T15:04:05.999999999Z0700", "2016-08-08T21:35:14.052975-0200") if err != nil { panic(err) } fmt.Println(t) }
您可以定义自己的 time
支持两种格式的字段类型:
type MyTime struct {
time.Time
}
func (self *MyTime) UnmarshalJSON(b []byte) (err error) {
s := string(b)
// Get rid of the quotes "" around the value.
// A second option would be to include them
// in the date format string instead, like so below:
// time.Parse(`"`+time.RFC3339Nano+`"`, s)
s = s[1:len(s)-1]
t, err := time.Parse(time.RFC3339Nano, s)
if err != nil {
t, err = time.Parse("2006-01-02T15:04:05.999999999Z0700", s)
}
self.Time = t
return
}
type Test struct {
Time MyTime `json:"time"`
}
在上面的示例中,我们采用预定义格式 time.RFC3339Nano
,其定义如下:
RFC3339Nano = "2006-01-02T15:04:05.999999999Z07:00"
并删除 :
"2006-01-02T15:04:05.999999999Z0700"
这里描述了 time.Parse
使用的时间格式:
https://golang.org/pkg/time/#pkg-constants
另请参阅 time.Parse
的文档
https://golang.org/pkg/time/#Parse
P.S。时间格式字符串中使用年份 2006
可能是因为那一年发布了 Golang 的第一个版本。