Golang中的time.Ticker,如何在偶数时间戳开始

huangapple go评论76阅读模式
英文:

Golang time.Ticker, how to begin on even timestamps

问题

我正在尝试在偶数时间戳上启动一个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

是否有一个优雅的解决方案?

英文:

I am attempting to begin a time.Ticker on even timestamps. Basically what I want is for this code:

package main

import (
    &quot;fmt&quot;
    &quot;time&quot;
)

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

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

    ticker.Stop()
}

To always print on an even 5-second interval:

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

Is there an elegant solution to this?

答案1

得分: 5

你可以延迟启动计时器,以接近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()))
英文:

You can delay the start of your ticker to get pretty close to an even 5 second time:

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

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

Or another way to get the correct delay with Time methods:

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

答案2

得分: 2

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

我能立即想到的最好的方法是计算到下一个5秒间隔的持续时间,并使用time.After在那个时间点获取一个信号。

playground链接

const fiveSeconds = int64(5 * time.Second)
for i := 0; i < 2; i++ {
    // 获取当前距离5秒间隔的偏移量。
    relativeTime := time.Now().UnixNano() % fiveSeconds
    // 获取当前5秒间隔中剩余的时间。
    waitTime := fiveSeconds - relativeTime
    // 等待相应的时间
    ch := time.After(time.Duration(waitTime))
    <-ch
    fmt.Println(time.Now())
}

它可能与精确的5秒间隔有些偏差,但如果您四舍五入,应该会非常接近。

英文:

Ticker will always tick relative to the time you start it. Also, if you don't receive fast enough, odd things can happen.

Best I can think of immediately is calculate the duration until the next 5 second interval and use time.After to get a signal at that time.

playground link

const fiveSeconds = int64(5 * time.Second)
for i := 0; i &lt; 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))
	&lt;-ch
	fmt.Println(time.Now())
}

It may be off a bit from exact 5 second intervals, but should be pretty close if you round it.

huangapple
  • 本文由 发表于 2015年10月22日 02:56:44
  • 转载请务必保留本文链接:https://go.coder-hub.com/33267106.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定