Golang time.Ticker,如何开始甚至时间戳

时间:2015-10-21 18:56:44

标签: go

我试图在偶数时间戳上开始time.Ticker。基本上我想要的是这段代码:

package main

import (
    "fmt"
    "time"
)

func main() {
    ticker := time.NewTicker(time.Second * 5)

    for i := 0; i < 2; i++ {
        select {
        case <-ticker.C:
            fmt.Println("Time: ", time.Now().Round(time.Second*1))
        }
    }

    ticker.Stop()
}

要始终以5秒的间隔打印:

Time:  2015-10-21 12:53:50 -0600 MDT
Time:  2015-10-21 12:53:55 -0600 MDT

这有一个优雅的解决方案吗?

2 个答案:

答案 0 :(得分:4)

你可以延迟你的自动收报机的开始时间非常接近甚至5秒钟:

fiveSec := int64(5 * time.Second)
time.Sleep(time.Duration(fiveSec - (time.Now().UnixNano() % fiveSec)))

ticker := time.NewTicker(time.Second * 5)

或者用Time方法获得正确延迟的另一种方法:

time.Sleep(time.Now().Truncate(5 * time.Second).Add(5 * time.Second).Sub(time.Now()))

答案 1 :(得分:2)

Ticker将始终相对于您启动它的时间进行勾选。此外,如果你收到的速度不够快,可能会发生奇怪的事情。

我能想到的最好是计算到下一个5秒间隔的持续时间,并使用time.After来获取当时的信号。

playground link

const fiveSeconds = int64(5 * time.Second)
for i := 0; i < 2; i++ {
    // get current offset from 5 second interval.
    relativeTime := time.Now().UnixNano() % fiveSeconds
    // get remaining time in current 5 second interval.
    waitTime := fiveSeconds - relativeTime
    // wait that long
    ch := time.After(time.Duration(waitTime))
    <-ch
    fmt.Println(time.Now())
}

它可能会从精确的5秒间隔开始略微偏离,但如果绕过它则应该非常接近。