Golang中国

for 以秒为单位, 循环匹配闹钟时间戳?不合理啊.

time包的定时器,和循环定时器都是以时间段duration做单位的.
难道每次启动时,根据设定的闹钟时间,计算出duration,然后time.AfterFuc()?
似乎这也不太合理啊.

求思路?


aaaaaaaa 于 2016-11-24 15:19 修改
2 回复
stevewang
#1 stevewang • 2016-11-24 19:47

计算出下一次闹钟起闹的时间与当前时间的间隔,然后设定这么长间隔时间的Timer不就可以了?

huangxianghan
#2 huangxianghan • 2016-12-22 17:14

`

//一次性闹钟
func AlarmAt(t *time.Time, alertFunc func()) {
    d := time.Duration(t.Unix() - time.Now().Unix()*int64(time.Second))
    time.AfterFunc(d, alertFunc)
}

//每日闹钟
func DailyAlarmClock(h, m, s int, alarmFunc func()) {

    //首次计算到下一次闹钟所需的时间间隔
    now := time.Now()
    nextAlarmTime := time.Date(now.Year(), now.Month(), now.Day(), h, m, s, 0, time.Local)
    if now.After(nextAlarmTime) {
        nextAlarmTime = nextAlarmTime.Add(time.Hour * 24)
    }
    d := time.Duration((nextAlarmTime.Unix() - now.Unix()) * int64(time.Second))

    //时间到后,再用time.Tick每日触发一次
    time.AfterFunc(d, func() {
        go alarmFunc()
        go AlarmLoop(time.Hour*24, alarmFunc)
    })
}

//每周闹钟,weekday 0 是星期天1-6周一至周六。注意:国际惯例,星期天才是新的一周的开始,不是星期一。
func WeeklyAlarmClock(weekday, h, m, s int, alarmFunc func()) {

    //首次计算到下一次闹钟所需的时间间隔
    now := time.Now()
    nextAlarmTime := time.Date(now.Year(), now.Month(), now.Day(), h, m, s, 0, time.Local)
    d := time.Duration((int64(weekday) - int64(nextAlarmTime.Weekday())) * int64(24*time.Hour))
    nextAlarmTime = nextAlarmTime.Add(d)
    if now.After(nextAlarmTime) {
        nextAlarmTime = nextAlarmTime.Add(time.Hour * 24 * 7)
    }
    d = time.Duration((nextAlarmTime.Unix() - now.Unix()) * int64(time.Second))

    //时间到后,再用time.Tick每周触发一次
    time.AfterFunc(d, func() {
        go alarmFunc()
        go AlarmLoop(time.Hour*24*7, alarmFunc)
    })
}

func AlarmLoop(d time.Duration, alarmFunc func()) {
    tc := time.Tick(d)
    for _ = range tc {
        go alarmFunc()
    }
}

`

需要 登录 后方可回复, 如果你还没有账号你可以 注册 一个帐号。