我无法解析Go-Gin中的日期/时间。

huangapple go评论69阅读模式
英文:

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.

huangapple
  • 本文由 发表于 2022年7月27日 18:38:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/73136442.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定