parsing - 无法将字符串解析为具有时区偏移量的时间,其中包含RFC3339带有看似矛盾的错误

标签 parsing go time timezone timezone-offset

我正在使用Golang和time.Time将给定的字符串解析为时间对象。
这里使用RFC3339和time.Parse是我的代码示例:

t, err := time.Parse(time.RFC3339, "2020-08-08T00:22:44Z07:00")
if err != nil {
   return nil, err
}
我得到以下错误。
当我包括时区偏移时,我得到:
ERRO[0002] parsing time "2020-08-08T00:22:44Z07:00": extra text: 07:00
当我不包括时区偏移量时,我会得到:
ERRO[0002] parsing time "2020-08-08T00:15:36" as "2006-01-02T15:04:05Z07:00": cannot parse "" as "Z07:00"
将时间解析为结构化对象时,如何避免此问题?

最佳答案

发布答案,因为此评论太长了。
Go Z常量time.RFC3339中存在字符"2006-01-02T15:04:05Z07:00"并不意味着而不是意味着符合该模式的日期应包括Z,后跟时区偏移量。
实际上,带有Z后跟其他任何内容的日期不是有效的RFC3339日期。因此,您的第一个错误extra text: 07:00Z代表“Zulu时间”,即UTC时区。根据RFC3339规范:

  Z           A suffix which, when applied to a time, denotes a UTC
              offset of 00:00; often spoken "Zulu" from the ICAO
              phonetic alphabet representation of the letter "Z".

因此,单独的Z 已经提供了时区信息,即UTC。
正如@Flimzy在评论中指出的那样,2020-08-08T00:22:44Z将是有效的RFC3339日期。
    t, err := time.Parse(time.RFC3339, "2020-08-08T00:22:44Z")
    if err != nil {
        panic(err)
    }
    fmt.Println(t) // 2020-08-08 00:22:44 +0000 UTC
现在,如果您进一步阅读RFC3339标准,则会看到以下定义:
time-zone       = "Z" / time-numoffset
time-numoffset  = ("+" / "-") time-hour [[":"] time-minute]

这意味着日期的时区部分为Z或偏移量。显然,由于Z已经表示偏移量00:00,因此在同一日期字符串中不能再有一个+/-HH:mm偏移量。
但这也意味着必须存在Z+/-HH:mm 。因此,如果将它们都删除,则会出现第二个错误:cannot parse "" as "Z07:00"解析器尝试将RFC_339字符串作为"2020-08-08T00:15:36"字符串读取,因此它期望在几秒钟(或毫秒,如果有)之后输入Z或偏移量。

总之,Go Z07:00模式中的time.RFC3339仅表示日期字符串应该包含时区的事实。有效的RFC3339日期字符串必须包含Z或偏移量。

关于parsing - 无法将字符串解析为具有时区偏移量的时间,其中包含RFC3339带有看似矛盾的错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63319133/

相关文章:

xml - 如何用golang解码最简单的xml

java - 当delay为0时,Timer.schedule调度多长时间?

c++ - 在 C++ 中,如何找到最大系统日期?

c - 在 C 中解析带引号的字符串

android - 使用 volley 获取 json 对象和数组

java - 解析没有等号(=)的cookie

go - 如何使用golang获取xen服务器内存、磁盘、网络和CPU信息?

通过引用去映射键,通过取消引用进行比较

c - 测量 TCP 连接速度

c - 如何在没有正则表达式的情况下用逗号(可选)后跟空格来拆分字符串?