我想写个闹钟程序, 请问思路是怎样的?

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

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

求思路?

共 2 个回复


stevewang

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

# 0

huangxianghan

`

//一次性闹钟
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()
    }
}

`

# 1