因为时区等问题,很多项目需要自定义时区和时间格式。还有需要自定义输出显示。
package timetool
import (
"database/sql/driver"
"fmt"
"time"
)
const TimeFormat = "2006-01-02 15:04:05"
const FormatISOTime = "2006-01-02T15:04:05Z"
const DayFormat = "20060102"
const SecondDateFormat = "20060102150405"
const FYear = "2006" //年
const FMonth = "01" //月
const FMonthNoZero = "1" //月,不带先导零
const FDay = "02" //日
const FDayNoZero = "2" //日,不带先导零
const FHour = "15" // 小时,24小时格式
const FMinute = "04" // 分钟
const FSecond = "05" // 秒
// 1. 创建 time.Time 类型的副本 XTime;
type MyTime struct {
time.Time
}
// 2. 为 MyTime 重写 MarshaJSON 方法,在此方法中实现自定义格式的转换;
func (t MyTime) MarshalJSON() ([]byte, error) {
loc := time.FixedZone(pkg.TimeLocal.TimeZone, pkg.TimeLocal.TimeOffset)
output := fmt.Sprintf("\"%s\"", t.In(loc).Format(TimeFormat))
return []byte(output), nil
}
// 3. 为 MyTime 实现 Value 方法,写入数据库时会调用该方法将自定义时间类型转换并写入数据库;
func (t MyTime) Value() (driver.Value, error) {
var zeroTime time.Time
if t.Time.UnixNano() == zeroTime.UnixNano() {
return nil, nil
}
return t.Time, nil
}
// 4. 为 MyTime 实现 Scan 方法,读取数据库时会调用该方法将时间数据转换成自定义时间类型;
func (t *MyTime) Scan(v interface{}) error {
value, ok := v.(time.Time)
if ok {
*t = MyTime{Time: value}
return nil
}
return fmt.Errorf("can not convert %v to timestamp", v)
}
func (t *MyTime) String() string {
loc := time.FixedZone(pkg.TimeLocal.TimeZone, pkg.TimeLocal.TimeOffset)
return t.In(loc).String()
}
func (t *MyTime) GetTime() time.Time {
loc := time.FixedZone(pkg.TimeLocal.TimeZone, pkg.TimeLocal.TimeOffset)
return t.In(loc)
}
func (t *MyTime) UnmarshalJSON(data []byte) (err error) {
// 空值不进行解析
if len(data) == 2 {
return
}
if string(data) == "null" {
return
}
var now time.Time
// 指定解析的格式
if now, err = time.ParseInLocation(TimeFormat, string(data), time.Local); err == nil {
*t = MyTime{now}
return
}
// 指定解析的格式
if now, err = time.ParseInLocation('"'+TimeFormat+'"', string(data), time.Local); err == nil {
*t = MyTime{now}
return
}
//解析默认格式
if now, err = time.ParseInLocation('"'+time.RFC3339+'"', string(data), time.Local); err == nil {
*t = MyTime{now}
return
}
return
}
func MyTimeNow() MyTime {
return MyTime{Time: time.Now()}
}
func NewMyTime(ts ...int64) *MyTime {
if len(ts) == 0 {
return &MyTime{Time: time.Now()}
}
loc := time.FixedZone(pkg.TimeLocal.TimeZone, pkg.TimeLocal.TimeOffset)
return &MyTime{
Time: time.Unix(ts[0], 0).In(loc),
}
}
JSON 关键点:
Gorm关键点: