|
|
package time_arrow
import ( "errors" "fmt" "log" "sort" "strings" "time" )
type TimeArrowType string
const ( TimeArrowTypeDayOfWeek TimeArrowType = "DAY_OF_WEEK" TimeArrowTypeDayOfMonth TimeArrowType = "DAY_OF_MONTH" TimeArrowTypeDateSlice TimeArrowType = "DATE_SLICE" )
type DateSlice struct { Start string `json:"start"` End string `json:"end"` }
type TimeArrow struct { Id int `json:"id"` Group string `json:"group"` Type TimeArrowType `json:"type"` //可选
DayOfWeek []int `json:"day_of_week"` DayOfMonth []int `json:"day_of_month"` DateSlice []DateSlice `json:"date_slice"` //必选
TimesOnDay []string `json:"times_on_day"` ExpandTags []string `json:"expand_tags"` ExpandValue interface{} `json:"expand_value"` Weights float64 `json:"weights"` }
type TimeArrows []TimeArrow
var GetData = func(group string) (TimeArrows, error) { return nil, errors.New("GetData 未实现") }
func isInDateSlice(t time.Time, ta TimeArrow) bool { for e := range ta.DateSlice { startStr := ta.DateSlice[e].Start startSc := strings.Split(startStr, " ") if len(startSc) < 2 { startSc = append(startSc, "00:00:00") } else { startSc[1] = timeCompletion(startSc[1]) } startStr = strings.Join(startSc, " ")
endStr := ta.DateSlice[e].End endSc := strings.Split(endStr, " ") if len(endSc) < 2 { endSc = append(endSc, "00:00:00") } else { endSc[1] = timeCompletion(endSc[1]) } endStr = strings.Join(endSc, " ")
startTime, err := time.Parse("2006-01-02 15:04:05", startStr) if err != nil { log.Println("时间段开始时间格式错误", startStr) continue }
endTime, err := time.Parse("2006-01-02 15:04:05", endStr) if err != nil { log.Println("时间段结束时间格式错误", startStr) continue }
if startTime.Unix() > endTime.Unix() { log.Println("开始时间必须小于结束时间", startStr, endStr) continue }
if t.After(startTime) && t.Before(endTime) { return true } } return false }
func isInWeekOfDay(t time.Time, ta TimeArrow) bool { nowWeekInt := int(t.Weekday()) for k := range ta.DayOfWeek { if ta.DayOfWeek[k] == nowWeekInt { return true } } return false }
func timeCompletion(a string) string { sc := strings.Split(a, ":") for len(sc) < 3 { sc = append(sc, "00") } return strings.Join(sc, ":") }
func isInDayOfMonth(t time.Time, ta TimeArrow) bool { day := t.Day() for e := range ta.DayOfMonth { if ta.DayOfMonth[e] == day { return true } } return false }
func isInTimeOfDay(t time.Time, ta TimeArrow) bool { if len(ta.TimesOnDay) == 0 { return true } for k := range ta.TimesOnDay { tsp := strings.Split(ta.TimesOnDay[k], "-") if len(tsp) < 2 { log.Println("必须为时间段:", ta.TimesOnDay[k]) continue }
start, end := tsp[0], tsp[1] start = timeCompletion(start) end = timeCompletion(end) startTime, err := time.Parse("2006-01-02 15:04:05", fmt.Sprintf("%s %s", t.Format("2006-01-02"), start)) if err != nil { log.Println("时间段开始时间格式错误", start) continue } endTime, err := time.Parse("2006-01-02 15:04:05", fmt.Sprintf("%s %s", t.Format("2006-01-02"), end)) if err != nil { log.Println("时间段结束时间格式错误", end) continue }
if startTime.Unix() > endTime.Unix() { log.Println("开始时间必须小于结束时间", end) continue }
if t.After(startTime) && t.Before(endTime) { return true } } return false }
func isInExpandTags(ta TimeArrow, expandTag string) bool { if len(ta.ExpandTags) == 0 { return true } for e := range ta.ExpandTags { if ta.ExpandTags[e] == expandTag { return true } }
return false }
//CreateDayOfWeekTypePlan 创建一个每周计划
func CreateDayOfWeekTypePlan(group string, dayOfWeek []int, timesOnDay []string, expandValue interface{}, expandTags []string, weights float64) TimeArrow { return TimeArrow{ Type: TimeArrowTypeDayOfWeek, Group: group, DayOfWeek: dayOfWeek, TimesOnDay: timesOnDay, ExpandValue: expandValue, ExpandTags: expandTags, Weights: weights, } }
//CreateDayOfMonthTypePlan 创建一个每月计划
func CreateDayOfMonthTypePlan(group string, dayOfMonth []int, timesOnDay []string, expandValue interface{}, expandTags []string, weights float64) TimeArrow { return TimeArrow{ Type: TimeArrowTypeDayOfMonth, Group: group, DayOfMonth: dayOfMonth, TimesOnDay: timesOnDay, ExpandValue: expandValue, ExpandTags: expandTags, Weights: weights, } }
//CreateDateSliceTypePlan 创建一个时间段计划
func CreateDateSliceTypePlan(group string, dateSlice []DateSlice, timesOnDay []string, expandValue interface{}, expandTags []string, weights float64) TimeArrow { return TimeArrow{ Type: TimeArrowTypeDateSlice, Group: group, DateSlice: dateSlice, TimesOnDay: timesOnDay, ExpandValue: expandValue, ExpandTags: expandTags, Weights: weights, } }
func GetHitTimeArrow(t time.Time, group string, expandTags ...string) (*TimeArrow, error) { ta, err := GetData(group) if err != nil { return nil, err } sort.Slice(ta, func(i, j int) bool { return ta[i].Weights > ta[j].Weights }) for e := range ta { //当天具体时间判断
if !isInTimeOfDay(t, ta[e]) { continue }
//扩展标签判断
if !isInExpandTags(ta[e], strings.Join(expandTags, "-")) { continue }
switch ta[e].Type { case TimeArrowTypeDayOfWeek: //一周中某一天是否判定
if isInWeekOfDay(t, ta[e]) { return &ta[e], nil } break case TimeArrowTypeDayOfMonth: //一月中某一天是否判定
if isInDayOfMonth(t, ta[e]) { return &ta[e], nil } break
case TimeArrowTypeDateSlice: //一月中某一天是否判定
if isInDateSlice(t, ta[e]) { return &ta[e], nil } break default: log.Println("类型错误:", ta[e].Type) } } return nil, nil }
|