为了账号安全,请及时绑定邮箱和手机立即绑定

解组格式不正确的日期时间

解组格式不正确的日期时间

Go
Qyouu 2022-03-07 14:42:54
背景我正在学习 Go,并且正在尝试对日期时间进行一些 JSON 解组。我有一些由我用 C 编写的程序生成的 JSON,我正在输出我认为是有效的ISO8601 / RFC3339时区偏移量。我正在使用strftime以下格式字符串:%Y-%m-%dT%H:%M:%S.%f%z(请注意,本机%f不支持strftime,我有一个用纳秒替换它的包装器)。这将产生以下结果:2016-08-08T21:35:14.052975+0200然而,在 Go 中解组这个是行不通的:https: //play.golang.org/p/vzOXbzAwdWpackage mainimport (    "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带有 a的格式:,但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"会忽略纳秒吗?
查看完整描述

2 回答

?
陪伴而非守候

TA贡献1757条经验 获得超8个赞

您可以定义自己的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"`

}

Try on Go Playground


在上面的示例中,我们采用了预定义的格式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的文档


PS2006时间格式字符串中使用年份可能是因为Golang的第一个版本是在那一年发布的。


查看完整回答
反对 回复 2022-03-07
?
潇潇雨雨

TA贡献1833条经验 获得超4个赞

你可以试试https://play.golang.org/p/IsUpuTKENg


包主


进口 (

    “fmt”

    “时间”

)


功能主要(){

    t, err := time.Parse("2006-01-02T15:04:05.999999999Z0700", "2016-08-08T21:35:14.052975-0200")

    如果错误!= nil {

        恐慌(错误)

    }

    fmt.Println(t)

}


查看完整回答
反对 回复 2022-03-07
  • 2 回答
  • 0 关注
  • 245 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信