package tool import ( "crypto/md5" "encoding/hex" "fmt" "reflect" "strconv" "strings" "time" ) const ( Layout = "2006-01-02 15:04:05" DateTime = "2006-01-02" DefaultExecTime = "0_0_0" ) // StringToTimeUnix 时间字符串转换成时间戳 // a.g 6_2_3 ===> 转换成 6天2小时3分钟后的时间戳 // TODO 需要优化代码写得太死,需要优化后兼容秒的场景 func StringToTimeUnix(execTimeStr string) int64 { var processAt = time.Now().Unix() if execTimeStr == DefaultExecTime { return processAt } execTime := strings.Split(execTimeStr, "_") if len(execTime) < 3 { return processAt } // 天数 days, _ := strconv.Atoi(execTime[0]) processAt += int64(days) * 24 * 60 * 60 // 小时 hours, _ := strconv.Atoi(execTime[1]) processAt += int64(hours) * 60 * 60 // 分钟 minutes, _ := strconv.Atoi(execTime[2]) processAt += int64(minutes) * 60 return processAt } func GetLocalTime(timeStr string) time.Time { execTime, _ := time.ParseInLocation(Layout, timeStr, time.Local) return execTime } // GetTargetByValueForTag 利用反射根据cond获取对应字段数据,主要tag必须为gorm // e.g person{Name:"ping",Age:12} // e.g GetTargetByTag(person,age) ==> 12 func GetTargetByValueForTag(target interface{}, cond string) interface{} { tf := reflect.Value{} // 判断是不是指针类型 if reflect.TypeOf(target).Kind() == reflect.Ptr { if reflect.ValueOf(target).IsNil() { // 空指针 return "" } tf = reflect.Indirect(reflect.ValueOf(target)) } else { tf = reflect.ValueOf(target) } typ := tf.Type() var condValue interface{} for k := 0; k < typ.NumField(); k++ { key := typ.Field(k).Tag.Get("gorm") if key != cond { continue } field := typ.Field(k).Name switch tf.FieldByName(field).Kind() { case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: condValue = tf.FieldByName(field).Int() case reflect.String: condValue = tf.FieldByName(field).String() } } return condValue } // GetTargetByTypeForTag 利用反射根据cond获取对应的字段类型默认值 // e.g person{Name:"ping",Age:12,EventStatus: fieldPb.EventStatus_ADMISSION} // e.g GetTargetByTypeForTag(person,age) ==> person{Name:"ping",Age:0,EventStatus: fieldPb.EventStatus_ADMISSION} // e.g GetTargetByTypeForTag(person,name) ==> person{Name:"",Age:12,EventStatus: fieldPb.EventStatus_ADMISSION} // e.g GetTargetByTypeForTag(person,event_status) ==> person{Name:"ping",Age:12,EventStatus: fieldPb.EventStatus_INVALID} func GetTargetByTypeForTag(target interface{}, cond string) { tf := reflect.TypeOf(target) // 判断是不是指针类型 if tf.Kind() == reflect.Ptr { tf = tf.Elem() } tv := reflect.ValueOf(target) if tv.Kind() == reflect.Ptr { tv = tv.Elem() } for i := 0; i < tf.NumField(); i++ { key := tf.Field(i).Tag.Get("gorm") if key != cond { continue } fieldName := tf.Field(i).Name tfKind := tf.Field(i).Type if tfKind.Kind() == reflect.String { tv.FieldByName(fieldName).SetString("") } if tfKind.Kind() == reflect.Int || tfKind.Kind() == reflect.Int8 || tfKind.Kind() == reflect.Int16 || tfKind.Kind() == reflect.Int32 || tfKind.Kind() == reflect.Int64 { tv.FieldByName(fieldName).SetInt(0) } if tfKind.Kind() == reflect.Uint || tfKind.Kind() == reflect.Uint8 || tfKind.Kind() == reflect.Uint16 || tfKind.Kind() == reflect.Uint32 || tfKind.Kind() == reflect.Uint64 { tv.FieldByName(fieldName).SetUint(0) } if tfKind.Kind() == reflect.Float32 || tfKind.Kind() == reflect.Float64 { tv.FieldByName(fieldName).SetFloat(0) } } } // MonthLastDay 获取当月最后一天 //eg 2023-01 => 2023-01-31 //eg 2023-02 => 2023-02-28 func MonthLastDay(yearMonth string) string { item := strings.Split(yearMonth, "-") if len(item) < 2 { return "" } year, _ := strconv.Atoi(item[0]) loc, _ := time.LoadLocation("Local") theTime, _ := time.ParseInLocation(Layout, fmt.Sprintf("%s-01 00:00:00", yearMonth), loc) return time.Date(year, theTime.Month()+1, 0, 0, 0, 0, 0, time.Local).Format("2006-01-02") } // TimeParseLocalUnix 获取当天零点的时间戳 // eg 2023-02-22 => 1676995200 func TimeParseLocalUnix(DayTime string) int64 { value := DayTime if len(DayTime) <= 11 { value = fmt.Sprintf("%s 00:00:00", DayTime) } loc, _ := time.LoadLocation("Local") theTime, _ := time.ParseInLocation(Layout, value, loc) return theTime.Unix() } // ColumNameValueJoinSqlString 获取columName对应的值拼接成sql语句 // eg columName = "a,b,c" ==> ('1','2','3') func ColumNameValueJoinSqlString(columName string, target interface{}) string { columNames := strings.Split(columName, ",") insertValue := "(" if target == nil { return insertValue } for _, c := range columNames { val := reflect.Value{} if reflect.TypeOf(target).Kind() == reflect.Ptr { val = reflect.Indirect(reflect.ValueOf(target)) } else { val = reflect.ValueOf(target) } typ := val.Type() strValue := "" for k := 0; k < typ.NumField(); k++ { key := typ.Field(k).Tag.Get("json") key = strings.ReplaceAll(key, ",omitempty", "") if key != c { continue } field := typ.Field(k).Name switch val.FieldByName(field).Kind() { case reflect.String: strValue = fmt.Sprintf("'%s'", val.FieldByName(field).String()) case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: strValue = fmt.Sprintf("%d", val.FieldByName(field).Int()) case reflect.Float64, reflect.Float32: strValue = fmt.Sprintf("%f", val.FieldByName(field).Float()) } } insertValue += fmt.Sprintf("%s,", strValue) } return fmt.Sprintf("%s)", strings.TrimRight(insertValue, ",")) } // ColumNameValue 获取columName 对应的值 // eg a => 1 func ColumNameValue(columName string, target interface{}) string { strValue := "" if target == nil { return strValue } val := reflect.Value{} if reflect.TypeOf(target).Kind() == reflect.Ptr { val = reflect.Indirect(reflect.ValueOf(target)) } else { val = reflect.ValueOf(target) } typ := val.Type() for k := 0; k < typ.NumField(); k++ { key := typ.Field(k).Tag.Get("json") key = strings.ReplaceAll(key, ",omitempty", "") if key != columName { continue } field := typ.Field(k).Name switch val.FieldByName(field).Kind() { case reflect.String: strValue = fmt.Sprintf("'%s'", val.FieldByName(field).String()) case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: strValue = fmt.Sprintf("%d", val.FieldByName(field).Int()) case reflect.Float64, reflect.Float32: strValue = fmt.Sprintf("%f", val.FieldByName(field).Float()) } } return strValue } // UnixTimeString unix时间戳转化成string eg 1673939363 => 2023-01-17 func UnixTimeString(unixTime int64) string { return time.Unix(unixTime, 0).Format(DateTime) } func Md5String(input string) string { s := md5.New() digest := strings.ReplaceAll(string(input), "\n", "") s.Write([]byte(digest)) return hex.EncodeToString(s.Sum(nil)) }