前文:http://www.4color.cn/view/35-golang-null-value-json
说到golang gin框架下空值的处理办法,其它数据类型都很完美,但time类型一直有问题
1、序列后 json格式达不到自己想要的格式
后来又查了一些资料:
采用自己定类型,然后做序列化处理。
如这篇文章介绍的基本上可以。
https://www.cnblogs.com/xiaofengshuyu/p/5664654.html
我自己用上之后,有个问题,就是提交的数据,我采用的BinJSON,会提示数据类型不正确,这就需要再做一个反序列化的处理。
//反序列化
func (t *Time) UnmarshalJSON(data []byte) error {
// Ignore null, like in the main JSON package.
if string(data) == "null" {
return nil
}
// Fractional seconds are handled implicitly by Parse.
newstring := string(data)
var err error
tt, err2 := time.ParseInLocation(timeFormart, newstring, time.Local)
if (err != nil) {
return err2
} else {
*t = Time(tt)
}
return err
}
同时在写入数据库时,该类型是不能识别,只能再做一个String。
然后为了输出的数据,不要输出0001-01-01这样的格式,还要对序列化程序做改进。
最终完美的代码如下:
type Time time.Time
const (
timeFormart = "2006-01-02 15:04:05"
)
//序列化
func (t Time) MarshalJSON() ([]byte, error) {
b := make([]byte, 0, len(timeFormart)+2)
b = append(b, '"')
if (t.Year() > 1000) {
b = time.Time(t).AppendFormat(b, timeFormart)
b = append(b, '"')
return b, nil
} else {
b = append(b, '"')
return b, nil
}
}
//反序列化
func (t *Time) UnmarshalJSON(data []byte) error {
// Ignore null, like in the main JSON package.
if string(data) == "null" {
return nil
}
// Fractional seconds are handled implicitly by Parse.
newstring := string(data)
var err error
tt, err2 := time.ParseInLocation(timeFormart, newstring, time.Local)
if (err != nil) {
return err2
} else {
*t = Time(tt)
}
return err
}
func (t Time) String() string {
return time.Time(t).Format(timeFormart)
}
func (t Time) Year() int {
return time.Time(t).Year()
}
func (t Time) Now() Time {
tt := Time(time.Now())
return tt
}
package helper
import (
"database/sql"
"log"
"tools"
"strings"
"time"
)
type TRows struct {
rows *sql.Rows
}
func NewRows(rows *sql.Rows) *TRows {
r := &TRows{}
r.rows = rows
return r
}
func (self *TRows) Scan(args ...interface{}) error {
args2 := []interface{}{}
for _, v := range args {
switch d := v.(type) {
case *int, *int64:
args2 = append(args2, &sql.NullInt64{})
case *float32, *float64:
args2 = append(args2, &sql.NullFloat64{})
case *string, *time.Time:
args2 = append(args2, &sql.NullString{})
case *tools.Time:
args2 = append(args2, &sql.NullString{})
default:
log.Println(v, d)
log.Fatal("不知道的类型 %T", d)
}
}
err := self.rows.Scan(args2...)
if err != nil {
return err
}
for i, v := range args {
switch d := v.(type) {
case *int:
*d = int(args2[i].(*sql.NullInt64).Int64)
case *int64:
*d = args2[i].(*sql.NullInt64).Int64
case *float64:
*d = args2[i].(*sql.NullFloat64).Float64
case *string:
*d = args2[i].(*sql.NullString).String
case *time.Time:
v := args2[i].(*sql.NullString)
newString := v.String
if (v.Valid) {
newString = strings.Replace(newString, "T", " ", -1)
newString = newString[0:strings.Index(newString, "+")]
}
log.Println(newString)
*d, _ = time.ParseInLocation("2006-01-02 15:04:05", newString, time.Local)
log.Println(*d)
case *tools.Time:
v := args2[i].(*sql.NullString)
newString := v.String
if (v.Valid) {
newString = strings.Replace(newString, "T", " ", -1)
newString = newString[0:strings.Index(newString, "+")]
}
log.Println(newString)
now1, _ := time.ParseInLocation("2006-01-02 15:04:05", newString, time.Local)
*d = tools.Time(now1)
log.Println(*d)
default:
log.Fatalln("不知道的类型222")
}
}
return nil
}
来源:信息来源