package mapstructure import ( "reflect" "time" ) // TimeToStringHook 时间转字符串 // 支持 *Time.time 转 string/*string // 不能用 Time.time 转,它会在上层认为是一个结构体数据而直接转成map,再到hook方法 func TimeToStringHook(layout string) DecodeHookFunc { return func( f reflect.Type, t reflect.Type, data interface{}) (interface{}, error) { // 判断目标类型是否为字符串 var strType string var isStrPointer *bool // 要转换的目标类型是否为指针字符串 if t == reflect.TypeOf(strType) { isStrPointer = new(bool) } else if t == reflect.TypeOf(&strType) { isStrPointer = new(bool) *isStrPointer = true } if isStrPointer == nil { return data, nil } // 判断类型是否为时间 timeType := time.Time{} if f != reflect.TypeOf(timeType) && f != reflect.TypeOf(&timeType) { return data, nil } // 将时间转换为字符串 var output string switch v := data.(type) { case *time.Time: output = v.Format(layout) case time.Time: output = v.Format(layout) default: return data, nil } if *isStrPointer { return &output, nil } return output, nil } } // TimeToUnixIntHook 时间转时间戳 // 支持 *Time.time 转 uint/uint32/uint64/int/int32/int64,支持带指针 // 不能用 Time.time 转,它会在上层认为是一个结构体数据而直接转成map,再到hook方法 func TimeToUnixIntHook() DecodeHookFunc { return func( f reflect.Type, t reflect.Type, data interface{}) (interface{}, error) { tkd := t.Kind() if tkd != reflect.Int && tkd != reflect.Int32 && tkd != reflect.Int64 && tkd != reflect.Uint && tkd != reflect.Uint32 && tkd != reflect.Uint64 { return data, nil } // 判断类型是否为时间 timeType := time.Time{} if f != reflect.TypeOf(timeType) && f != reflect.TypeOf(&timeType) { return data, nil } // 将时间转换为字符串 var output int64 switch v := data.(type) { case *time.Time: output = v.Unix() case time.Time: output = v.Unix() default: return data, nil } switch tkd { case reflect.Int: return int(output), nil case reflect.Int32: return int32(output), nil case reflect.Int64: return output, nil case reflect.Uint: return uint(output), nil case reflect.Uint32: return uint32(output), nil case reflect.Uint64: return uint64(output), nil default: return data, nil } } }