package utils import ( "errors" "math" "reflect" "strconv" "strings" "time" timeconv "github.com/Andrew-M-C/go.timeconv" "github.com/beego/beego/v2/core/validation" "gitlab.fjmaimaimai.com/allied-creation/performance/pkg/domain" ) // ValidateCommand 验证输入参数 func ValidateCommand(commandType interface{}) error { valid := validation.Validation{} b, err := valid.Valid(commandType) if err != nil { return err } if !b { elem := reflect.TypeOf(commandType).Elem() for _, validErr := range valid.Errors { field, isExist := elem.FieldByName(validErr.Field) if isExist { if tag := field.Tag.Get("cname"); len(tag) > 0 { return errors.New(strings.Replace(validErr.Message, validErr.Field, tag, -1)) } else { return errors.New(validErr.Message) } } else { return errors.New(validErr.Message) } } } return nil } // FormatFloatDecimal 格式化小数点位数 func FormatFloatDecimal(num float64, decimal int) string { d := float64(1) if decimal > 0 { d = math.Pow10(decimal) // 10的N次方 } // math.trunc作用就是返回浮点数的整数部分 return strconv.FormatFloat(math.Trunc(num*d)/d, 'f', -1, 64) } // NextTime 0点时刻为标准计算 func NextTime(now0 time.Time, start time.Time, kpiCycle int) time.Time { year, month, day := start.Date() // 起始时间0点时刻 start0 := time.Date(year, month, day, 0, 0, 0, 0, time.Local) var nextTime time.Time switch kpiCycle { case domain.KpiCycleDay: nextTime = now0 // 当前时间的0点开始发送 break case domain.KpiCycleWeek: offsetSeconds := int64(now0.Sub(start0).Seconds()) offsetDay := offsetSeconds / (24 * 60 * 60) cycleCount := int(offsetDay)/7 + 1 nextTime = timeconv.AddDate(start0, 0, 0, cycleCount*7) break case domain.KpiCycleOneMonth: offsetMonth := SubMonth(now0, start0) nextTime = timeconv.AddDate(start0, 0, offsetMonth, 0) if nextTime.Before(now0) { nextTime = timeconv.AddDate(nextTime, 0, 1, 0) } break case domain.KpiCycleTwoMonth: offsetMonth := SubMonth(now0, start0) multiple := float64(offsetMonth) / 2 if multiple == 0 { multiple = 1 } else { multiple = math.Ceil(multiple) } nextTime = timeconv.AddDate(start0, 0, int(multiple)*2, 0) if nextTime.Before(now0) { nextTime = timeconv.AddDate(nextTime, 0, 2, 0) } break case domain.KpiCycleThreeMonth: offsetMonth := SubMonth(now0, start0) multiple := float64(offsetMonth) / 3 if multiple == 0 { multiple = 1 } else { multiple = math.Ceil(multiple) } nextTime = timeconv.AddDate(start0, 0, int(multiple)*3, 0) if nextTime.Before(now0) { nextTime = timeconv.AddDate(nextTime, 0, 3, 0) } break case domain.KpiCycleSixMonth: offsetMonth := SubMonth(now0, start0) multiple := float64(offsetMonth) / 6 if multiple == 0 { multiple = 1 } else { multiple = math.Ceil(multiple) } nextTime = timeconv.AddDate(start0, 0, int(multiple)*6, 0) if nextTime.Before(now0) { nextTime = timeconv.AddDate(nextTime, 0, 6, 0) } break case domain.KpiCycleYear: offsetMonth := SubMonth(now0, start0) multiple := float64(offsetMonth) / 12 if multiple == 0 { multiple = 1 } else { multiple = math.Ceil(multiple) } nextTime = timeconv.AddDate(start0, 0, int(multiple)*12, 0) if nextTime.Before(now0) { nextTime = timeconv.AddDate(nextTime, 0, 12, 0) } break } return nextTime } // SubMonth 计算日期相差多少月 func SubMonth(t1, t2 time.Time) (month int) { y1 := t1.Year() y2 := t2.Year() m1 := int(t1.Month()) m2 := int(t2.Month()) d1 := t1.Day() d2 := t2.Day() yearInterval := y1 - y2 // 如果 d1的 月-日 小于 d2的 月-日 那么 yearInterval-- 这样就得到了相差的年数 if m1 < m2 || (m1 == m2 && d1 < d2) { yearInterval-- } // 获取月数差值 monthInterval := (m1 + 12) - m2 if d1 < d2 { monthInterval-- } monthInterval %= 12 month = yearInterval*12 + monthInterval return } // NextTimeInc 0点时刻为标准计算 func NextTimeInc(start time.Time, kpiCycle int) time.Time { year, month, day := start.Date() // 起始时间0点时刻 start0 := time.Date(year, month, day, 0, 0, 0, 0, time.Local) var nextTime time.Time switch kpiCycle { case domain.KpiCycleDay: nextTime = timeconv.AddDate(start0, 0, 0, 1) // 当前时间的下一天开始发送 break case domain.KpiCycleWeek: nextTime = timeconv.AddDate(start0, 0, 0, 7) break case domain.KpiCycleOneMonth: nextTime = timeconv.AddDate(start0, 0, 1, 0) break case domain.KpiCycleTwoMonth: nextTime = timeconv.AddDate(start0, 0, 2, 0) break case domain.KpiCycleThreeMonth: nextTime = timeconv.AddDate(start0, 0, 3, 0) break case domain.KpiCycleSixMonth: nextTime = timeconv.AddDate(start0, 0, 6, 0) break case domain.KpiCycleYear: nextTime = timeconv.AddDate(start0, 1, 0, 0) break } return nextTime }