问题
我们知道go语言的time.Time类型在转为json的时候,输出的是UTC的时间,而我们绝大部分时候使用的都是Datetime格式。
其实解决问题的核心就是使用自定义字段,实现json的MarshaJSON方法
一、示例:原生time.Time的json输出为UTC格式
例如,我们有一个商品结构体Good,里边的CreatedAt和UpdateAt为time.Time类型
package main
import (
"encoding/json"
"fmt"
"time"
)
type Good struct {
ID int `json:"id"`
Name string `json:"name"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
func main() {
good := Good{123, "chenqiognhe", time.Now(), time.Now()}
bytes, _ := json.Marshal(good)
fmt.Printf("%s", bytes)
}
输出结果为
{
"id": 123,
"name": "chenqiognhe",
"created_at": "2020-07-31T14:27:10.035542+08:00",
"updated_at": "2020-07-31T14:27:10.035542+08:00"
}
可以看到created_at和updated_at都是UTC的格式
二、自定义结构体Datetime(缺点是需要手动转换类型)
如下,我们定义了一个time.Time的别名结构体Datetime
package main
import (
"encoding/json"
"fmt"
"time"
)
type Datetime time.Time
func (t Datetime) MarshalJSON() ([]byte, error) {
var stamp = fmt.Sprintf(""%s"", time.Time(t).Format("2006-01-02 15:04:05"))
return []byte(stamp), nil
}
type Good struct {
ID int `json:"id"`
Name string `json:"name"`
CreatedAt Datetime `json:"created_at"`
UpdatedAt Datetime `json:"updated_at"`
}
func main() {
good := Good{123, "chenqiognhe", Datetime(time.Now()), Datetime(time.Now())}
bytes, _ := json.Marshal(good)
fmt.Printf("%s", bytes)
}
输出如下
{
"id": 123,
"name": "chenqiognhe",
"created_at": "2020-07-31 14:27:39",
"updated_at": "2020-07-31 14:27:39"
}
三、自定义结构体Datetime+自定义临时结构体(最佳方案)
package main
import (
"encoding/json"
"fmt"
"time"
)
type DateTime time.Time
func (t DateTime) MarshalJSON() ([]byte, error) {
var stamp = fmt.Sprintf(""%s"", time.Time(t).Format("2006-01-02 15:04:05"))
return []byte(stamp), nil
}
type Good struct {
ID int `json:"id"`
Name string `json:"name"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
func (t Good) MarshalJSON() ([]byte, error) {
type TmpJSON Good
return json.Marshal(&struct {
TmpJSON
CreatedAt DateTime `json:"created_at"`
UpdatedAt DateTime `json:"updated_at"`
}{
TmpJSON: (TmpJSON)(t),
CreatedAt: DateTime(t.CreatedAt),
UpdatedAt: DateTime(t.UpdatedAt),
})
}
func main() {
good := Good{123, "chenqiognhe", time.Now(), time.Now()}
bytes, _ := json.Marshal(good)
fmt.Printf("%s", bytes)
}
这里我们给Good加了一个MarshalJSON方法实现,并通过临时结构体TmpJSON,指定了CreatedAt和UpdatedAt字段为Datetime类型。
使用Good结构体,无需转换time.Time为Datetime,可以直接使用time.Time的所有方法。
输出结果为
{
"id": 123,
"name": "chenqiognhe",
"created_at": "2020-07-31 14:28:12",
"updated_at": "2020-07-31 14:28:12"
}