循环定时功能

业务场景:如某个提醒功能,可以设定重复定时,设定周一某个时间点循环提醒。

重复定时截图

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
// 计算出 weekdays 里距离 compareTime 最近的一个未来时间点
// weekdays: [1,2,3,4,5,6,7]周一、周二...周日, houMinute: 时分,compareTime:对比时间点,一般设置为time.Now()
func LatestTimeByWeekday(weekdays []int, hourMinute string, compareTime time.Time) (time.Time, error) {
    if len(weekdays) <= 0 {
        return time.Time{}, errors.New("weekdays参数不能为空")
    }

    // 对比时间点为周几,默认周日设置为7
    weekday := int(compareTime.Weekday())
    if weekday == 0 {
        weekday = 7
    }

    sort.Slice(weekdays, func(i, j int) bool {
        return weekdays[i] < weekdays[j]
    })

    getTime := func(addDay int) (time.Time, error) {
        date := compareTime.AddDate(0, 0, addDay).Format("2006-01-02 ") + hourMinute + ":00"
        return time.ParseInLocation("2006-01-02 15:04:05", date, time.Local)
    }

    var tmpTimeArr []time.Time
    for _, v := range weekdays {
        if weekday == v {
            // 检查当天时间点符不符合条件
            tmpTime, err := getTime(0)
            if err != nil {
                return time.Time{}, err
            }

            // 当天时间点不符合条件,直接取下一周的时间
            if tmpTime.Before(compareTime) || tmpTime.Equal(compareTime) {
                tmpTime, err := getTime(7)
                if err != nil {
                    return time.Time{}, err
                }
                tmpTimeArr = append(tmpTimeArr, tmpTime)
            } else {
                return tmpTime, nil
            }
        } else if weekday < v {
            tmpTime, err := getTime(v - weekday)
            if err != nil {
                return time.Time{}, err
            }
            return tmpTime, nil
        } else {
            tmpTime, err := getTime(7 - weekday + v)
            if err != nil {
                return time.Time{}, err
            }
            tmpTimeArr = append(tmpTimeArr, tmpTime)
        }
    }

    if len(tmpTimeArr) > 0 {
        return tmpTimeArr[0], nil
    }

    return time.Time{}, errors.New("异常错误")
}