目前正在处理时间戳,我想将单调时钟读取部分存储在一个变量中。
假设我有这个:2022-03-31 10:20:26.370463 +0200 CEST m=+0.007725255
,那么我想在不同的var中获得m=+0.007725255
,或者至少在+0.007725255
部分中。Go to get中的惯用方法是什么?
Gotime.Time
存储2个时间戳:
- 挂钟
- 过程开始后的单调持续时间(可选,通过
time.Now
(
m=+0.007725255
表示自过程开始以来的单调持续时间(当存在于time.Time
中时(。
Go通过在初始化期间记录time.startNano
时间戳来计算此偏移量(非公开(。CCD_ 9使用CCD_ 10来计算存储在CCD_ 11中的单调持续时间。没有简单的公共API可以直接检索这个值,因为永远不需要它。
在实践中,您应该简单地减去当前过程中通过time.Now
生成的2个时间戳,结果将是单调的持续时间。如果您需要知道进程启动后的持续时间,则应在初始化期间记录启动时间戳。
示例:
package main
import (
"errors"
"fmt"
"math"
"strconv"
"strings"
"time"
)
func main() {
t0 := time.Now()
fmt.Println("...example event...")
time.Sleep(time.Millisecond)
t1 := time.Now()
fmt.Println("Event start:", t0)
fmt.Println("Event completed:", t1)
fmt.Println("=== Not recommended ===")
offsetT0, _ := monoOffset(t0)
fmt.Println("Parsed start offset:", offsetT0)
startNano, _ := calculateStartNano()
fmt.Println("Calculate start offset via startNano: ", t0.Sub(startNano))
fmt.Println("=== Recommended ===")
fmt.Println("Example event duration:", t1.Sub(t0))
fmt.Println("Time since startup", time.Since(t0))
}
// You should never need anything below here (code smell).
func monoOffset(t time.Time) (time.Duration, error) {
// Recommend strings.Cut on Go1.18+.
parts := strings.Split(t.String(), " m=")
if len(parts) != 2 {
return 0, errors.New("missing monotonic offset")
}
seconds, err := strconv.ParseFloat(parts[1], 64)
if err != nil {
return 0, err
}
nanos := math.Round(seconds * 1e9)
return time.Duration(nanos), nil
}
func calculateStartNano() (time.Time, error) {
now := time.Now()
offset, err := monoOffset(now)
if err != nil {
return time.Time{}, err
}
return now.Add(-offset), nil
}
输出:
...example event...
Event start: 2022-04-16 16:54:25.088159496 +1000 AEST m=+0.000079273
Event completed: 2022-04-16 16:54:25.089438935 +1000 AEST m=+0.001358685
=== Not recommended ===
Parsed start offset : 79.273µs
Calculate start offset via startNano: 79.273µs
=== Recommended ===
Example event duration: 1.279412ms
Time since startup 2.016789ms
单调时钟只用于时间之间的差异。单调时钟的绝对值是未定义的,你不应该试图得到它。我认为你真正想要的时间戳是从基准时间开始的持续时间。
func init() {
baseTime = time.Now()
}
// NowTimestamp returns really just the duration from the base time
func NowTimestamp() time.Duration {
return time.Now().Sub(baseTime)
}