这里有篇文章,是自定义mysql的datetime类型
https://segmentfault.com/a/1190000022264001?utm_source=tag-newest
根据这篇文章的提示,我写了自定义mysql的date类型,前端传年月日,后端识别并返回年月日的数据
因为功能上暂时没用到新增,所以value方法我没做修改,如果有需要的朋友可以参考上面链接自己做
展示成果
代码
package datetypes
import (
"database/sql/driver"
"fmt"
"strconv"
"time"
)
type Date time.Time
//MarshalJSON 实现了 Marshaler 接口
func (s *Date) MarshalJSON() ([]byte, error) {
y, m, d := time.Time(*s).Date()
str := strconv.Quote(time.Date(y, m, d, 0, 0, 0, 0, time.Time(*s).Location()).Format("2006-01-02"))
return []byte(str), nil
}
//UnmarshalJSON 实现了 Unmarshaler 接口
func (s *Date) UnmarshalJSON(bytes []byte) error {
// 空值不进行解析
if len(bytes) == 2 {
*s = Date(time.Time{})
return nil
}
//_, err = time.ParseInLocation("2006-01-02 15:04:05", str, time.Local)
decode, err := strconv.Unquote(string(bytes))
if err != nil {
return err
}
parseTime, err := time.Parse("2006-01-02 15:04:05", decode+" 00:00:00")
//parseTime, err := time.ParseInLocation("2006-01-02 15:04:05", decode+" 00:00:00", time.Local)
if err != nil {
fmt.Println(fmt.Sprintf("err:%v\n", err.Error()))
return err
}
*s = Date(parseTime)
return nil
}
/*func (s *Date) Scan(value interface{}) error {
bytes, ok := value.([]byte)
if !ok {
return errors.New(fmt.Sprint("Failed to unmarshal JSONB value:", value))
}
result := new(Date)
err := json.Unmarshal(bytes, &result)
*s = *result
return err
}*/
// 检出 mysql 时调用
func (s *Date) Scan(v interface{}) error {
// mysql 内部日期的格式可能是 2006-01-02 15:04:05 +0800 CST 格式,所以检出的时候还需要进行一次格式化
tTime, _ := time.Parse("2006-01-02 15:04:05 +0800 CST", v.(time.Time).String())
*s = Date(tTime)
return nil
}
// Value return json value, implement driver.Valuer interface
func (s Date) Value() (driver.Value, error) {
if &s == nil {
return nil, nil
}
bytes, err := s.MarshalJSON()
if err != nil {
return nil, err
}
return strconv.Unquote(string(bytes))
}
2021-03-19
在dto转VO这里,我用的是 "github.com/jinzhu/copier" 这个人的工具。
他的单个对象转换有点问题。
需要修改为
// 检出 mysql 时调用
func (s *Date) Scan(v interface{}) error {
// mysql 内部日期的格式可能是 2006-01-02 15:04:05 +0800 CST 格式,所以检出的时候还需要进行一次格式化
//tTime, _ := time.Parse("2006-01-02 15:04:05 +0800 CST", v.(time.Time).String())
switch v.(type) {
case time.Time:
tTime, _ := time.Parse("2006-01-02 15:04:05 +0800 CST", v.(time.Time).String())
*s = Date(tTime)
goto done
case Date:
*s = v.(Date)
goto done
case *Date:
v1 := v.(*Date)
*s = *v1
goto done
default:
return errors.New("can not convert to Date")
}
done:
return nil
一开始list转换没问题,debug许久发现,是他直接把list的地址指了过去吐了。单个对象用的反射就会走到这个方法