3136352472
5 years ago
3 changed files with 523 additions and 1 deletions
-
2.gitignore
-
212core.go
-
310core_test.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 |
||||
|
} |
@ -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") |
||||
|
} |
||||
|
|
||||
|
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue