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

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

Golang time.Ticker, how to begin on even timestamps

问题

我正在尝试在偶数时间戳上启动一个time.Ticker。基本上,我想要的是这段代码:

  1. package main
  2. import (
  3. "fmt"
  4. "time"
  5. )
  6. func main() {
  7. ticker := time.NewTicker(time.Second * 5)
  8. for i := 0; i < 2; i++ {
  9. select {
  10. case <-ticker.C:
  11. fmt.Println("Time: ", time.Now().Round(time.Second*1))
  12. }
  13. }
  14. ticker.Stop()
  15. }

始终在5秒的偶数间隔上打印:

  1. Time: 2015-10-21 12:53:50 -0600 MDT
  2. 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:

  1. package main
  2. import (
  3. &quot;fmt&quot;
  4. &quot;time&quot;
  5. )
  6. func main() {
  7. ticker := time.NewTicker(time.Second * 5)
  8. for i := 0; i &lt; 2; i++ {
  9. select {
  10. case &lt;-ticker.C:
  11. fmt.Println(&quot;Time: &quot;, time.Now().Round(time.Second*1))
  12. }
  13. }
  14. ticker.Stop()
  15. }

To always print on an even 5-second interval:

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

Is there an elegant solution to this?

答案1

得分: 5

你可以延迟启动计时器,以接近5秒的时间:

  1. fiveSec := int64(5 * time.Second)
  2. time.Sleep(time.Duration(fiveSec - (time.Now().UnixNano() % fiveSec)))
  3. ticker := time.NewTicker(time.Second * 5)

或者使用Time方法获取正确的延迟:

  1. 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:

  1. fiveSec := int64(5 * time.Second)
  2. time.Sleep(time.Duration(fiveSec - (time.Now().UnixNano() % fiveSec)))
  3. ticker := time.NewTicker(time.Second * 5)

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

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

答案2

得分: 2

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

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

playground链接

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

它可能与精确的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

  1. const fiveSeconds = int64(5 * time.Second)
  2. for i := 0; i &lt; 2; i++ {
  3. // get current offset from 5 second interval.
  4. relativeTime := time.Now().UnixNano() % fiveSeconds
  5. // get remaining time in current 5 second interval.
  6. waitTime := fiveSeconds - relativeTime
  7. // wait that long
  8. ch := time.After(time.Duration(waitTime))
  9. &lt;-ch
  10. fmt.Println(time.Now())
  11. }

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:

确定