From a9d46e1d8f06ad0b37e5b4899438a1b75187cee3 Mon Sep 17 00:00:00 2001 From: 3136352472 <3136352472> Date: Tue, 9 Jun 2020 14:15:17 +0800 Subject: [PATCH] init --- .gitignore | 2 +- core.go | 212 ++++++++++++++++++++++++++++++++++++++++ core_test.go | 310 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 523 insertions(+), 1 deletion(-) create mode 100644 core.go create mode 100644 core_test.go diff --git a/.gitignore b/.gitignore index 9a3a8d8..aa58dc0 100644 --- a/.gitignore +++ b/.gitignore @@ -11,4 +11,4 @@ # Output of the go coverage tool, specifically when used with LiteIDE *.out - +.idea \ No newline at end of file diff --git a/core.go b/core.go new file mode 100644 index 0000000..f56a22b --- /dev/null +++ b/core.go @@ -0,0 +1,212 @@ +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 +} + +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 +} diff --git a/core_test.go b/core_test.go new file mode 100644 index 0000000..f27d82a --- /dev/null +++ b/core_test.go @@ -0,0 +1,310 @@ +package time_arrow + +import ( + "testing" + "time" +) + +func Test_isInWeekOfDay(t *testing.T) { + ti, err := time.Parse("2006-01-02 15:04:05", "2020-06-08 00:00:00") + if err != nil { + panic(err) + } + ok := isInWeekOfDay(ti, TimeArrow{ + DayOfWeek: []int{ + 1, + 3, + }, + }) + if !ok { + t.Fatal("error") + } + ok = isInWeekOfDay(ti, TimeArrow{ + DayOfWeek: []int{ + 6, + 3, + 2, + }, + }) + if ok { + t.Fatal("error") + } + ok = isInWeekOfDay(ti, TimeArrow{}) + if ok { + t.Fatal("error") + } +} + +func Test_timeCompletion(t *testing.T) { + if timeCompletion("12") != "12:00:00" { + t.Fatal("error") + } + if timeCompletion("17:00") != "17:00:00" { + t.Fatal("error") + } +} + +func Test_isInTimeOfDay(t *testing.T) { + ti, err := time.Parse("2006-01-02 15:04:05", "2020-06-08 17:18:00") + if err != nil { + panic(err) + } + ok := isInTimeOfDay(ti, TimeArrow{ + TimesOnDay: []string{ + "1:21", + "1:21-2:22", + "17:00-18:00", + }, + }) + if !ok { + t.Fatal("error") + } + ok = isInTimeOfDay(ti, TimeArrow{ + TimesOnDay: []string{ + "17:00-17:10", + "18:00-19:00", + }, + }) + if ok { + t.Fatal("error") + } +} + +func Test_isInDateSlice(t *testing.T) { + ti, err := time.Parse("2006-01-02 15:04:05", "2020-06-08 17:18:00") + if err != nil { + panic(err) + } + + ok := isInDateSlice(ti, TimeArrow{ + DateSlice: []DateSlice{}, + }) + + if ok { + t.Fatal("error") + } + + ok = isInDateSlice(ti, TimeArrow{ + DateSlice: []DateSlice{ + { + Start: "2020-06-05 17:18", + End: "2020-06-07", + }, + }, + }) + + if ok { + t.Fatal("error") + } + + ok = isInDateSlice(ti, TimeArrow{ + DateSlice: []DateSlice{ + { + Start: "2020-06-05 17:18", + End: "2020-06-07", + }, + { + Start: "2020-06-07 17:18", + End: "2020-06-09", + }, + }, + }) + + if !ok { + t.Fatal("error") + } +} + +func Test_isInExpandTags(t *testing.T) { + ok := isInExpandTags(TimeArrow{ + ExpandTags: []string{}, + }, "一号场") + + if !ok { + t.Fatal("error") + } + + ok = isInExpandTags(TimeArrow{ + ExpandTags: []string{ + "一号场", + "二号场", + "四号场", + }, + }, "一号场") + + if !ok { + t.Fatal("error") + } + + ok = isInExpandTags(TimeArrow{ + ExpandTags: []string{ + "一号场", + "二号场", + "四号场", + }, + }, "三号场") + + if ok { + t.Fatal("error") + } + +} + +func TestGetHitTimeArrow(t *testing.T) { + tas := TimeArrows{ + { + Type: TimeArrowTypeDayOfWeek, + DayOfWeek: []int{ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + }, + ExpandTags: []string{ + "一号场", + "二号场", + "三号场", + "四号场", + }, + ExpandValue: 0, + Weights: 0, + }, + { + Type: TimeArrowTypeDayOfWeek, + DayOfWeek: []int{ + 6, + 0, + }, + ExpandTags: []string{ + "一号场", + "二号场", + "四号场", + }, + ExpandValue: 30, + Weights: 1, + }, + { + Type: TimeArrowTypeDayOfWeek, + DayOfWeek: []int{ + 6, + 0, + }, + ExpandTags: []string{ + "三号场", + }, + ExpandValue: 60, + Weights: 1, + }, + { + Type: TimeArrowTypeDayOfMonth, + DayOfMonth: []int{ + 3, + 5, + }, + ExpandValue: 12, + Weights: 2, + }, + { + Type: TimeArrowTypeDateSlice, + DateSlice: []DateSlice{ + { + Start: "2020-04-05", + End: "2020-05-05", + }, + { + Start: "2020-06-07 17:18", + End: "2020-06-09", + }, + }, + ExpandValue: 5, + Weights: 3, + }, + { + Type: TimeArrowTypeDateSlice, + DateSlice: []DateSlice{ + { + Start: "2020-04-05", + End: "2020-05-05", + }, + { + Start: "2020-06-07 17:18", + End: "2020-06-09", + }, + }, + TimesOnDay: []string{ + "18-19", + }, + ExpandValue: 180, + Weights: 4, + }, + } + + GetData = func(group string) (arrows TimeArrows, e error) { + return tas, nil + } + + ti, err := time.Parse("2006-01-02 15:04:05", "2020-06-01 17:18:00") + if err != nil { + panic(err) + } + + result, err := GetHitTimeArrow(ti, "", "一号场") + if err != nil || result == nil { + t.Fatal("error") + panic(err) + } + + if result.ExpandValue.(int) != 0 { + t.Fatal("error") + } + + ti = ti.AddDate(0, 0, -1) + result, err = GetHitTimeArrow(ti, "", "一号场") + if err != nil || result == nil { + t.Fatal("error") + panic(err) + } + + if result.ExpandValue.(int) != 30 { + t.Fatal("error", result.ExpandValue.(int)) + } + result, err = GetHitTimeArrow(ti, "", "三号场") + if err != nil || result == nil { + t.Fatal("error") + panic(err) + } + + if result.ExpandValue.(int) != 60 { + t.Fatal("error") + } + + ti, err = time.Parse("2006-01-02 15:04:05", "2020-04-11 17:18:00") + if err != nil { + panic(err) + } + + result, err = GetHitTimeArrow(ti, "", "三号场") + if err != nil || result == nil { + t.Fatal("error") + panic(err) + } + + if result.ExpandValue.(int) != 5 { + t.Fatal("error") + } + + ti = ti.Add(time.Hour) + result, err = GetHitTimeArrow(ti, "", "三号场") + if err != nil || result == nil { + t.Fatal("error") + panic(err) + } + + if result.ExpandValue.(int) != 180 { + t.Fatal("error") + } + +}