报警就像Golang中的计时器功能一样

时间:2016-01-26 07:51:16

标签: go timer

有没有办法设计一个在Golang的特定未来时间到期的计时器?我指的是一个在凌晨2点到期的计时器(让当前时间为12AM)。我知道一种方法是使用,

 timer(target_future_time - current_time)   

但似乎并不是一种确切的方法(在考虑执行时间时可能不准确)。有人可以帮忙吗?

2 个答案:

答案 0 :(得分:1)

在golang中,也许有两种方式创建自动收报机,如下所示:

package main

import (
    "fmt"
    "time"
)

func main() {
    //第一种实现方式 
    ticker1 := time.NewTicker(1 * time.Second)
    i := 1
    for c := range ticker1.C {
        i++
        fmt.Println(c.Format("2006/01/02 15:04:05.999999999"))
        if i > 5 {
            ticker1.Stop()
            break
        }
    }
    fmt.Println(time.Now().Format("2006/01/02 15:04:05.999999999"), " 1 Finished.")

    //第二种实现方式 
    i = 1
    ticker2 := time.AfterFunc(1*time.Second, func() {
        i++
        fmt.Println(time.Now().Format("2006/01/02 15:04:05.999999999"))
    })

    for {
        select {
        case <-ticker2.C:
            fmt.Println("nsmei")
        case <-time.After(3 * time.Second):
            if i <= 5 {
                ticker2.Reset(1 * time.Second)
                continue
            }
            goto BRK
        }
    BRK:
        ticker2.Stop()
        break
    }
    fmt.Println(time.Now().Format("2006/01/02 15:04:05.999999999"), " 2 Finished.")
}

输出:

2016/01/26 16:46:34.261248567
2016/01/26 16:46:35.256381743
2016/01/26 16:46:36.259717152
2016/01/26 16:46:37.260320837
2016/01/26 16:46:38.259312704
2016/01/26 16:46:38.259410752  1 Finished.
2016/01/26 16:46:39.260604274
2016/01/26 16:46:42.261091322
2016/01/26 16:46:45.263136257
2016/01/26 16:46:48.264193517
2016/01/26 16:46:51.265655137
2016/01/26 16:46:53.265722632  2 Finished.

根据执行情况,第一个比第二个更精确。

在您的情况下,您可以使用time.Time.Sub()来计算持续时间,并执行一旦使用第二种方法,其余的使用第一种方法。

我希望这些可以帮到你!

答案 1 :(得分:0)

以下代码可达到您的目的。您所要做的就是以下面main()函数中显示的方式调用ScheduleAlarm()。

package main

import (
    "strings"
    "strconv"
    "fmt"
    "time"
)

// A struct for representing time.
type Time struct {
    Hh int // Hours.
    Mm int // Minutes.
    Ss int // Seconds.
}

func main() {
    /*
    Set the alarm as shown below.
    Time must be specified in 24 hour clock format.
    Also, pass the callback to be called after the alarm is triggered.
    */
    alarm := ScheduleAlarm(Time{23, 28, 0}, func() {
        fmt.Println("alarm received")
    })

    // Do your stuff.
    for i := 0; i < 10; i++ {
        fmt.Println(i)
        time.Sleep(2 * time.Second)
    }

    // Don't forget to call the below line whenever you want to block.
    <-alarm
}

// Call this function to schedule the alarm. The callback will be called after the alarm is triggered.
func ScheduleAlarm(alarmTime Time, callback func() ()) (endRecSignal chan string) {
    endRecSignal = make(chan string)
    go func() {
        timeSplice := strings.Split(time.Now().Format("15:04:05"), ":")
        hh, _ := strconv.Atoi(timeSplice[0])
        mm, _ := strconv.Atoi(timeSplice[1])
        ss, _ := strconv.Atoi(timeSplice[2])

        startAlarm := GetDiffSeconds(Time{hh, mm, ss}, alarmTime)

        // Setting alarm.
        time.AfterFunc(time.Duration(startAlarm) * time.Second, func() {
            callback()
            endRecSignal <- "finished recording"
            close(endRecSignal)
        })
    }()
    return
}

func GetDiffSeconds(fromTime, toTime Time) int {
    fromSec := GetSeconds(fromTime)
    toSec := GetSeconds(toTime)
    diff := toSec - fromSec

    if diff < 0 {
        return diff + 24 * 60 * 60
    } else {
        return diff
    }
}

func GetSeconds(time Time) int {
    return time.Hh * 60 * 60 + time.Mm * 60 + time.Ss
}

希望这有帮助。