Go 自定义日期时间格式解析解决方案 - 解决 `parsing time xx as xx: cannot parse xx as xx` 错误

最近在解析 Go 的日期数据格式时(mysqldatetime 类型)时遇到个问题,在网上搜了很多方案都试了以后发现不可行,于是自己尝试解决后将解决方案发布出来。

Go 自身的 time.Time 类型默认解析的日期格式是 RFC3339 标准,也就是 2006-01-02T15:04:05Z07:00 的格式。如果我们想要在 GinshouldBindJSON 方法中,传入 YYYY-MM-DD hh:mm:ss 格式的日期格式作为 time.Time 类型的值,就会引发类似于 parsing time xx as xx: cannot parse xx as xx 的报错信息。这是因为 time.Time 类型默认支持的日期格式与我们传入的格式不同,导致解析出错。。

遇到这个问题后,我在网上找了很多方案,发现都失败了。有的可以完成正常解析,但是无法正确写入到数据库。有的可以正常写入和写出,但是会使得 gin 自带的验证规则如 binding:"required" 规则失效,失去校验的功能。

自定义 LocalTime 类型

解决这个问题的关键就是解决 c.ShouldBindJSONgorm.Updates 的问题,我们需要定义一个新的 Time 类型和自定义的日期格式解析(如下),并将我们的 struct 结构体 datetime 字段指定为我们自定义的类型(如下)

  • 自定义 LocalTime 类型
// model.LocalTime
package model

const TimeFormat = "2006-01-02 15:04:05"

type LocalTime time.Time
  • 业务代码结构
// You Application Struct
package order

type OrderTest struct {
   
	OrderId     int              `json:"order_id"`
	Test        string           `json:"test"`
	PaymentTime *model.LocalTime `json:"payment_time" binding:"required"`
	TestTime    *model.LocalTime `json:"test_time"`
}

解析 JSON 格式数据 - UnmarshalJSONMarshalJSON

c.ShouldBindJSON 时,会调用 field.UnmarshalJSON 方法,所以我们需要先设置这个方法(如下):

func (t *LocalTime) UnmarshalJSON(data []byte) (err error) {
   
  // 空值不进行解析
	if len(data) == 2 {
   
		*t = LocalTime(time.Time{
   })
		return
	}

  // 指定解析的格式
	now, err := time.Parse(`"`+TimeFormat+`"`, string(data))
	*t = LocalTime(now)
	return
}

UnmarshalJSON 解析后,shouldBindJSON 就可以正常解析 YYYY-MM-DD hh:mm:ss 格式的日期格式了,这样一来就解决了 parsing time xx as xx: cannot parse xx as xx 的问题。

既然解决了 shouldBindJSON 的问题,我们还需要解决 c.JSON 时解析值的问题(实现如下)

func 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值