50 lines
1.5 KiB
Go
50 lines
1.5 KiB
Go
package service
|
||
|
||
import (
|
||
"strconv"
|
||
"strings"
|
||
"time"
|
||
)
|
||
|
||
// parseClock 解析 HH:MM,非法输入回退 09:00。
|
||
func parseClock(at string) (int, int) {
|
||
parts := strings.SplitN(at, ":", 2)
|
||
if len(parts) != 2 {
|
||
return 9, 0
|
||
}
|
||
h, e1 := strconv.Atoi(parts[0])
|
||
m, e2 := strconv.Atoi(parts[1])
|
||
if e1 != nil || e2 != nil || h < 0 || h > 23 || m < 0 || m > 59 {
|
||
return 9, 0
|
||
}
|
||
return h, m
|
||
}
|
||
|
||
// DigestDue 判断团队日报摘要是否到达自动生成时间:now 已过当天 at(HH:MM)。
|
||
func DigestDue(at string, now time.Time) bool {
|
||
hh, mm := parseClock(at)
|
||
due := time.Date(now.Year(), now.Month(), now.Day(), hh, mm, 0, 0, now.Location())
|
||
return !now.Before(due)
|
||
}
|
||
|
||
// NextAutoUpdate 计算下一次自动更新的时间点(纯函数,便于测试)。
|
||
// mode: daily | everyNDays | everyNHours;at 为 HH:MM;last 为上次执行时间(调用方保证非零)。
|
||
func NextAutoUpdate(mode string, interval int, at string, last, now time.Time) time.Time {
|
||
if interval < 1 {
|
||
interval = 1
|
||
}
|
||
hh, mm := parseClock(at)
|
||
switch mode {
|
||
case "everyNHours":
|
||
return last.Add(time.Duration(interval) * time.Hour)
|
||
case "everyNDays":
|
||
return time.Date(last.Year(), last.Month(), last.Day(), hh, mm, 0, 0, last.Location()).AddDate(0, 0, interval)
|
||
default: // daily:今天的 HH:MM;若上次已在该时点之后执行过,则推到明天。
|
||
t := time.Date(now.Year(), now.Month(), now.Day(), hh, mm, 0, 0, now.Location())
|
||
if !last.Before(t) {
|
||
t = t.AddDate(0, 0, 1)
|
||
}
|
||
return t
|
||
}
|
||
}
|