package types import ( "database/sql/driver" "fmt" "time" ) // 默认时间格式 const dateFormat = "2006-01-02 15:04:05.000" // DateTime 自定义时间类型 type DateTime time.Time // Scan implements the Scanner interface. func (dt *DateTime) Scan(value any) error { // mysql 内部日期的格式可能是 2006-01-02 15:04:05 +0800 CST 格式,所以检出的时候还需要进行一次格式化 tTime, _ := time.ParseInLocation("2006-01-02 15:04:05 +0800 CST", value.(time.Time).String(), time.Local) *dt = DateTime(tTime) return nil } // Value implements the driver Valuer interface. func (dt DateTime) Value() (driver.Value, error) { // 0001-01-01 00:00:00 属于空值,遇到空值解析成 null 即可 if dt.String() == "0001-01-01 00:00:00.000" { return nil, nil } return []byte(dt.Format(dateFormat)), nil } // 用于 fmt.Println 和后续验证场景 func (dt DateTime) String() string { return dt.Format(dateFormat) } // Format 格式化 func (dt DateTime) Format(fm string) string { return time.Time(dt).Format(fm) } // After 时间比较 func (dt *DateTime) After(now time.Time) bool { return time.Time(*dt).After(now) } // Before 时间比较 func (dt *DateTime) Before(now time.Time) bool { return time.Time(*dt).Before(now) } // IBefore 时间比较 func (dt *DateTime) IBefore(now DateTime) bool { return dt.Before(time.Time(now)) } // SubTime 对比 func (dt DateTime) SubTime(t time.Time) time.Duration { return dt.ToTime().Sub(t) } // Sub 对比 func (dt DateTime) Sub(t DateTime) time.Duration { return dt.ToTime().Sub(t.ToTime()) } // ToTime 转换为golang的时间类型 func (dt DateTime) ToTime() time.Time { return time.Time(dt).Local() } // IsNil 是否为空值 func (dt DateTime) IsNil() bool { return dt.Format(dateFormat) == "0001-01-01 00:00:00.000" } // Unix 实现Unix函数 func (dt DateTime) Unix() int64 { return dt.ToTime().Unix() } // EndOfCentury 获取本世纪最后时间 func (dt DateTime) EndOfCentury() DateTime { yearEnd := time.Now().Local().Year()/100*100 + 99 return DateTime(time.Date(yearEnd, 12, 31, 23, 59, 59, 999999999, time.Local)) } // ======== 序列化 ======== // MarshalJSON 时间到字符串 func (dt DateTime) MarshalJSON() ([]byte, error) { // 过滤掉空数据 if dt.IsNil() { return []byte("\"\""), nil } output := fmt.Sprintf(`"%s"`, dt.Format("2006-01-02 15:04:05")) return []byte(output), nil } // UnmarshalJSON 字符串到时间 func (dt *DateTime) UnmarshalJSON(b []byte) error { if len(b) == 2 { *dt = DateTime{} return nil } // 解析指定的格式 //now, err := time.ParseInLocation(`"`+dateFormat+`"`, string(b), time.Local) now, err := time.ParseInLocation(dateFormat, string(b), time.Local) *dt = DateTime(now) return err }