gin将响应的时间格式化 YYYY-MM-DD HH:MM:SS
- 创建
model/time_type.go
go
package model
import (
"database/sql/driver"
"encoding/json"
"fmt"
"time"
)
// LocalTime 自定义时间类型(格式化为 YYYY-MM-DD HH:MM:SS)
type LocalTime time.Time
// 常量:时间格式化模板
const timeFormat = "2006-01-02 15:04:05"
// MarshalJSON 实现 JSON 序列化接口(返回格式化后的字符串)
func (t LocalTime) MarshalJSON() ([]byte, error) {
// 将自定义时间类型转为 time.Time
tt := time.Time(t)
if tt.IsZero() {
return []byte("null"), nil // 空时间返回 null
}
// 格式化时间为字符串并包裹双引号(JSON 字符串格式)
return json.Marshal(tt.Format(timeFormat))
}
// UnmarshalJSON 实现 JSON 反序列化接口(接收格式化字符串转为时间)
func (t *LocalTime) UnmarshalJSON(data []byte) error {
// 空值处理
if string(data) == "null" {
*t = LocalTime(time.Time{})
return nil
}
// 解析字符串为时间
tt, err := time.Parse(`"`+timeFormat+`"`, string(data))
if err != nil {
return err
}
*t = LocalTime(tt)
return nil
}
// Value 实现 driver.Valuer 接口(数据库存储时的格式)
func (t LocalTime) Value() (driver.Value, error) {
tt := time.Time(t)
if tt.IsZero() {
return nil, nil
}
return tt.Format(timeFormat), nil
}
// Scan 实现 sql.Scanner 接口(从数据库读取时解析为 LocalTime)
func (t *LocalTime) Scan(v interface{}) error {
if v == nil {
*t = LocalTime(time.Time{})
return nil
}
switch v.(type) {
case time.Time:
*t = LocalTime(v.(time.Time))
case []byte:
tt, err := time.Parse(timeFormat, string(v.([]byte)))
if err != nil {
return err
}
*t = LocalTime(tt)
case string:
tt, err := time.Parse(timeFormat, v.(string))
if err != nil {
return err
}
*t = LocalTime(tt)
default:
return fmt.Errorf("不支持的时间类型:%T", v)
}
return nil
}
// String 实现 Stringer 接口(打印时返回格式化字符串)
func (t LocalTime) String() string {
return time.Time(t).Format(timeFormat)
}
- 修改
create_at或create_time等时间字段的类型
go
package model
import (
"gorm.io/gorm"
)
type User struct {
ID uint64 `gorm:"primarykey;comment:用户ID" json:"id"`
CreatedAt LocalTime `gorm:"comment:创建时间" json:"created_at"`
UpdatedAt LocalTime `gorm:"comment:更新时间" json:"updated_at"`
DeletedAt gorm.DeletedAt `gorm:"index;comment:删除时间" json:"deleted_at"` // 软删除
}