go 自定义mysql的date类型

这里有篇文章,是自定义mysql的datetime类型

https://segmentfault.com/a/1190000022264001?utm_source=tag-newest

 

根据这篇文章的提示,我写了自定义mysql的date类型,前端传年月日,后端识别并返回年月日的数据

因为功能上暂时没用到新增,所以value方法我没做修改,如果有需要的朋友可以参考上面链接自己做

 

展示成果

go 自定义mysql的date类型_第1张图片

 

代码

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的地址指了过去吐了。单个对象用的反射就会走到这个方法

你可能感兴趣的:(Go)