go - 限制格式化持续时间中的有效数字

标签 go formatting duration

我正在对一些不可预测的 I/O 进行计时。这段代码

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

产品

123.456789ms

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

我不喜欢这种精度 - 我更愿意只报告两位或三位有效数字。是否有一种简单的方法来限制格式化指令%v或类似的精度?

最佳答案

前言:我在 github.com/icza/gox 中发布了这个实用程序,请参阅 timex.Round()

<小时/>

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

控制结果小数位的一种方法是在打印之前使用 Duration.Truncate()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
}

让我们用不同的持续时间来测试它:

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()
}

输出将是(在 Go Playground 上尝试):

duration       0 digits       1 digit        2 digits       3 digits
-----------------------------------------------------------------------
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       

关于go - 限制格式化持续时间中的有效数字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58414820/

相关文章:

GoLang 文件传输停止没有任何错误

java - 如何在 Java 记录器消息中插入制表符?

android - AndEngine 动画之间的时长

python - queue.Queue 上的多路复用?

go - 如何跨go包使用常量

go - 除了可移植性和安全性原因之外,为什么有人想通过 WebAssembly 在 Web 浏览器中运行他们现有的 go/rust/c++ 应用程序?

css - 使用 CSS 更改表格布局

java - 使用Apache POI在Excel中使用千位分隔符格式化数字

c++ - 使用 ctime 和 time_t 的输出差异

java - 在java中查找MP3文件的长度,最好以毫秒为单位,就像python的mutagen库一样