在格式化的持续时间内限制有效数字

问题描述 投票:2回答:2

我正在安排一些不可预测的I / O。此代码

started := time.Now()
time.Sleep(123456789 * time.Nanosecond) // unpredictable process    
fmt.Printf("%v", time.Since(started))

产品

123.456789ms

我喜欢自动选择和打印单位刻度(ms,μs,ns等),因为我事先不知道定时操作是否需要微秒,毫秒或秒才能完成。

我不喜欢这种精度-我只希望报告两位或三位有效数字。是否有simple方法来限制格式指令%v或类似格式中的精度?

go formatting duration
2个回答
2
投票

我不认为有简单的方法,因为当使用默认格式(例如%v)打印时,将调用Duration.String()来生成字符串表示形式。它返回Duration.String()值,因此格式选项(如小数位数)不再适用。

控制结果小数位数的一种方法是在打印前使用stringDuration.Truncate()截断或舍入持续时间。

当然,持续时间应被截断或舍入为的单位取决于持续时间的值,但是逻辑并不难:

Duration.Truncate()

让我们以不同的持续时间对其进行测试:

Duration.Round()

输出将是(在Duration.Round()上尝试):

var divs = []time.Duration{
    time.Duration(1), time.Duration(10), time.Duration(100), time.Duration(1000)}

func round(d time.Duration, digits int) time.Duration {
    switch {
    case d > time.Second:
        d = d.Round(time.Second / divs[digits])
    case d > time.Millisecond:
        d = d.Round(time.Millisecond / divs[digits])
    case d > time.Microsecond:
        d = d.Round(time.Microsecond / divs[digits])
    }
    return d
}

2
投票

[ds := []time.Duration{ time.Hour + time.Second + 123*time.Millisecond, // 1h0m1.123s time.Hour + time.Second + time.Microsecond, // 1h0m1.000001s 123456789 * time.Nanosecond, // 123.456789ms 123456 * time.Nanosecond, // 123.456µs 123 * time.Nanosecond, // 123ns } for _, d := range ds { fmt.Printf("%-15v", d) for digits := 0; digits <= 3; digits++ { fmt.Printf("%-15v", round(d, digits)) } fmt.Println() } 正在使用Duration.String(),因此您必须编写一个自定义格式的函数,例如:

Go Playground

或者您可以使用格式化程序定义新类型,然后使用新类型进行打印:

1h0m1.123s     1h0m1s         1h0m1.1s       1h0m1.12s      1h0m1.123s     
1h0m1.000001s  1h0m1s         1h0m1s         1h0m1s         1h0m1s         
123.456789ms   123ms          123.5ms        123.46ms       123.457ms      
123.456µs      123µs          123.5µs        123.46µs       123.456µs      
123ns          123ns          123ns          123ns          123ns       
© www.soinside.com 2019 - 2024. All rights reserved.