英文:
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 (
"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()
}
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
在那个时间点获取一个信号。
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.
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())
}
It may be off a bit from exact 5 second intervals, but should be pretty close if you round it.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论