go-wxhelper/pkg/types/date.go
2024-01-19 12:06:30 +08:00

145 lines
3.2 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package types
import (
"database/sql/driver"
"fmt"
"github.com/vmihailenco/msgpack/v5"
"strings"
"time"
)
// 默认时间格式
const dateFormat = "2006-01-02"
// Date 自定义时间类型
type Date time.Time
// Scan implements the Scanner interface.
func (dt *Date) Scan(value any) error {
// mysql 内部日期的格式可能是 2006-01-02 15:04:05 +0800 CST 格式,所以检出的时候还需要进行一次格式化
tTime, _ := time.Parse("2006-01-02 15:04:05 +0800 CST", value.(time.Time).String())
*dt = Date(tTime)
return nil
}
// Value implements the driver Valuer interface.
func (dt Date) Value() (driver.Value, error) {
// 0001-01-01 00:00:00 属于空值,遇到空值解析成 null 即可
if dt.String() == "0001-01-01" {
return nil, nil
}
return []byte(dt.Format(dateFormat)), nil
}
// 用于 fmt.Println 和后续验证场景
func (dt Date) String() string {
return dt.Format(dateFormat)
}
// Format 格式化
func (dt Date) Format(fm string) string {
return time.Time(dt).Format(fm)
}
// After 时间比较
func (dt *Date) After(now time.Time) bool {
return time.Time(*dt).After(now)
}
// Before 时间比较
func (dt *Date) Before(now time.Time) bool {
return time.Time(*dt).Before(now)
}
// IBefore 时间比较
func (dt *Date) IBefore(now Date) bool {
return dt.Before(time.Time(now))
}
// SubTime 对比
func (dt Date) SubTime(t time.Time) time.Duration {
return dt.ToTime().Sub(t)
}
// Sub 对比
func (dt Date) Sub(t Date) time.Duration {
return dt.ToTime().Sub(t.ToTime())
}
// ToTime 转换为golang的时间类型
func (dt Date) ToTime() time.Time {
return time.Time(dt)
}
// IsNil 是否为空值
func (dt Date) IsNil() bool {
return dt.Format(dateFormat) == "0001-01-01"
}
// Unix 实现Unix函数
func (dt Date) Unix() int64 {
return dt.ToTime().Unix()
}
// ======== 序列化 JSON ========
// MarshalJSON 时间到字符串
func (dt Date) MarshalJSON() ([]byte, error) {
// 过滤掉空数据
if dt.IsNil() {
return []byte("\"\""), nil
}
output := fmt.Sprintf(`"%s"`, dt.Format(dateFormat))
return []byte(output), nil
}
// UnmarshalJSON 字符串到时间
func (dt *Date) UnmarshalJSON(b []byte) error {
if len(b) == 2 {
*dt = Date{}
return nil
}
// 解析指定的格式
var now time.Time
var err error
if strings.HasPrefix(string(b), "\"") {
now, err = time.ParseInLocation(`"`+dateFormat+`"`, string(b), time.Local)
} else {
now, err = time.ParseInLocation(dateFormat, string(b), time.Local)
}
*dt = Date(now)
return err
}
// ======== 序列化 RPCX ========
// EncodeMsgpack
// @description: 序列化(由于Msgpack不支持时区所以这里序列化成字符串)
// @receiver dt
// @param enc
// @return error
func (dt Date) EncodeMsgpack(enc *msgpack.Encoder) error {
return enc.Encode(dt.Format("2006-01-02"))
}
// DecodeMsgpack
// @description: 反序列化(由于Msgpack不支持时区所以这里从字符串反序列化)
// @receiver dt
// @param dec
// @return error
func (dt *Date) DecodeMsgpack(dec *msgpack.Decoder) error {
var dtStr string
err := dec.Decode(&dtStr)
if err != nil {
return err
}
var tm time.Time
tm, err = time.ParseInLocation("2006-01-02", dtStr, time.Local)
if err != nil {
return err
}
*dt = Date(tm)
return nil
}