You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Echo框架如何将yyyy-MM-dd格式日期字符串绑定到含time.Time的结构体

问题原因

Go标准库time.Time默认的JSON/表单反序列化仅支持带时分秒和时区的RFC3339格式(如2006-01-02T15:04:05Z07:00),你传入的2021-09-27纯日期格式不符合默认解析规则,因此需要自定义时间类型实现对应的反序列化接口适配场景。

解决方案

1. 定义自定义日期类型

新建自定义日期类型,实现Echo绑定需要的JSON、表单反序列化方法,按需补充序列化、GORM适配方法:

package model

import (
	"time"
	"database/sql/driver" // 适配GORM需要导入该包
)

// CustomDate 自定义支持yyyy-MM-dd格式的日期类型
type CustomDate time.Time

// UnmarshalJSON 实现JSON反序列化接口,适配JSON请求
func (d *CustomDate) UnmarshalJSON(data []byte) error {
	if len(data) == 2 && string(data) == `""` {
		*d = CustomDate(time.Time{})
		return nil
	}
    // 如需UTC时区替换time.Local为time.UTC即可
	t, err := time.ParseInLocation(`"2006-01-02"`, string(data), time.Local)
	if err != nil {
		return err
	}
	*d = CustomDate(t)
	return nil
}

// UnmarshalForm 实现表单反序列化接口,适配form-data/urlencoded请求
func (d *CustomDate) UnmarshalForm(value string) error {
	if value == "" {
		*d = CustomDate(time.Time{})
		return nil
	}
	t, err := time.ParseInLocation("2006-01-02", value, time.Local)
	if err != nil {
		return err
	}
	*d = CustomDate(t)
	return nil
}

// MarshalJSON 可选:实现JSON序列化,返回响应时也输出yyyy-MM-dd格式
func (d CustomDate) MarshalJSON() ([]byte, error) {
	t := time.Time(d)
	if t.IsZero() {
		return []byte(`""`), nil
	}
	return []byte(`"` + t.Format("2006-01-02") + `"`), nil
}

// Value 可选:实现GORM的Value接口,兼容数据库写入
func (d CustomDate) Value() (driver.Value, error) {
	t := time.Time(d)
	if t.IsZero() {
		return nil, nil
	}
	return t, nil
}

// Scan 可选:实现GORM的Scan接口,兼容数据库读取
func (d *CustomDate) Scan(value interface{}) error {
	if v, ok := value.(time.Time); ok {
		*d = CustomDate(v)
		return nil
	}
	return nil
}

2. 修改结构体字段类型

把TestModel中Date字段的类型从time.Time替换为自定义的CustomDate:

type TestModel struct {
  Date     CustomDate `json:"date" form:"date" gorm:"index;type:date"`
  gorm.Model
}

3. 原有业务代码无需改动

你之前写的参数绑定逻辑可以直接运行,需要使用标准time.Time类型时强制转换即可:

func CreateDiary(c echo.Context) error {
    var getData model.TestModel
    if err := (&echo.DefaultBinder{}).BindBody(c, &getData); err != nil {
        fmt.Print(err.Error())
        return c.JSON(400, map[string]string{"msg": "日期格式错误,请传入yyyy-MM-dd格式"})
    }
    // 转标准time.Time示例:standardTime := time.Time(getData.Date)
    return c.JSON(200, getData)
}

内容的提问来源于stack exchange,提问作者Choi yun seok

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 04:36:03