英文:
I can not parse date/time in Go - Gin
问题
我正在发送这个 JSON:
{"origin":{"lat":23.589367061768648,"lng":58.42860314995051},"destination":null,"vehicle":"WATER_TANKER_600GL","scheduled_time":"2022-07-27T14:16:00Z04:00"}
Golang Gin 处理函数:
func (config *Config) CreateOrder(c *gin.Context) {
userID := auth.GetToken(c).ID()
data := &struct {
Origin models.Origin `json:"origin" binding:"required"`
Vehicle VehicleType `json:"vehicle" binding:"required"`
Destination *models.Destination `json:"destination"`
ScheduledTime *time.Time `json:"scheduled_time"`
}{}
if err := c.ShouldBindWith(data, binding.JSON); err != nil {
fmt.Println(err) // -> 打印以下错误
res.UnprocessableEntity(c, fmt.Sprintf("%s", err))
return
}
// 其余的代码
}
我得到了这个错误:
将时间“\ "2022-07-27T14:16:00Z04:00\"解析为“\ "2006-01-02T15:04:05Z07:00\"”时出错:无法将“04:00\"解析为“\ \""
英文:
I am sending this json:
{"origin":{"lat":23.589367061768648,"lng":58.42860314995051},"destination":null,"vehicle":"WATER_TANKER_600GL","scheduled_time":"2022-07-27T14:16:00Z04:00"}
Golang Gin handler function:
func (config *Config) CreateOrder(c *gin.Context) {
userID := auth.GetToken(c).ID()
data := &struct {
Origin models.Origin `json:"origin" binding:"required"`
Vehicle VehicleType `json:"vehicle" binding:"required"`
Destination *models.Destination `json:"destination" `
ScheduledTime *time.Time `json:"scheduled_time"`
}{}
if err := c.ShouldBindWith(data, binding.JSON); err != nil {
fmt.Println(err) // -> prints the below error
res.UnprocessableEntity(c, fmt.Sprintf("%s", err))
return
}
// rest of the code
}
I get this error:
parsing time "\"2022-07-27T14:16:00Z04:00\"" as "\"2006-01-02T15:04:05Z07:00\"": cannot parse "04:00\"" as "\""
答案1
得分: 2
请注意,JSON没有定义日期或时间戳数据类型。将时间戳作为JSON字符串传输是可能的,但是如何解释或应该如何解释该时间戳字符串并没有明确规定。标准库(encoding/json
包)支持从JSON字符串解组time.Time
值,但是要求这些值符合RFC 3339标准,否则解组将失败。
time.Time
实现了json.Unmarshaler
接口,而Time.UnmarshalJSON()
方法要求JSON字符串必须采用RFC 3339布局,即:
RFC3339 = "2006-01-02T15:04:05Z07:00"
布局中的Z
表示:
数字时区偏移的格式如下:
"-0700" ±hhmm "-07:00" ±hh:mm "-07" ±hh
将格式中的符号替换为Z会触发ISO 8601的行为,将Z打印为UTC区域的偏移量。 因此:
"Z0700" Z或±hhmm "Z07:00" Z或±hh:mm "Z07" Z或±hh
这意味着如果时间具有UTC偏移量,则应为:
"2022-07-27T14:16:00Z"
如果时间具有+04:00
时区,则应为:
"2022-07-27T14:16:00+04:00"
输入"2022-07-27T14:16:00Z04:00"
不符合RFC 3339的规范。要么更改源代码以提供符合RFC 3339的时间戳字符串,要么如果无法或不想这样做,则可以创建自定义类型来实现json.Unmarshaler
接口,并自行处理这种非RFC 3339格式。
英文:
Note that JSON does not define a date or timestamp data type. Transferring a timestamp as a JSON string is possible, but how that timestamp string is interpreted–or should be interpreted–is not written in stone. The standard lib (the encoding/json
package) supports unmarshaling time.Time
values from JSON strings, but it does so by requiring them to adhere the RFC 3339 standard, else the unmarshaling will fail.
time.Time
implements json.Unmarshaler
, and Time.UnmarshalJSON()
states that the JSON string must be in RFC 3339 layout which is:
RFC3339 = "2006-01-02T15:04:05Z07:00"
The Z
in the layout means:
> Numeric time zone offsets format as follows:
>
> "-0700" ±hhmm
> "-07:00" ±hh:mm
> "-07" ±hh
> Replacing the sign in the format with a Z triggers the ISO 8601 behavior of printing Z instead of an offset for the UTC zone. Thus:
>
> "Z0700" Z or ±hhmm
> "Z07:00" Z or ±hh:mm
> "Z07" Z or ±hh
Which means if the time has UTC offset, it should be
"2022-07-27T14:16:00Z"
If the time has +04:00
zone, it should be
"2022-07-27T14:16:00+04:00"
The input "2022-07-27T14:16:00Z04:00"
is invalid for RFC 3339. Either change your source to provide RFC 3339 compliant timestamp strings, or if you can't or don't want to, you may create your custom type that implements json.Unmarshaler
, and you handle this non-RFC 3339 format yourself.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论