亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

限制格式化持續時間中的有效數字

限制格式化持續時間中的有效數字

Go
慕無忌1623718 2023-07-31 15:06:26
我正在對一些不可預測的 I/O 進行計時。這段代碼started := time.Now()time.Sleep(123456789 * time.Nanosecond) // unpredictable process    fmt.Printf("%v", time.Since(started))生產123.456789ms我喜歡自動選擇和打印單位刻度(ms、μs、ns 等),因為我事先不知道定時操作是否需要微秒、毫秒或秒才能完成。我不喜歡這種精度 - 我寧愿只報告兩位或三位有效數字。有沒有一種簡單的方法來限制格式指令或類似指令的精度%v?
查看完整描述

3 回答

?
鴻蒙傳說

TA貢獻1865條經驗 獲得超7個贊

我認為沒有簡單的方法,因為當使用默認格式(例如%v)打印時,Duration.String()被調用來生成字符串表示形式。它返回一個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? ? ? ?


查看完整回答
反對 回復 2023-07-31
?
婷婷同學_

TA貢獻1844條經驗 獲得超8個贊

%v使用 Duration.String(),因此您必須編寫自定義格式函數,例如:


func fmtTime(in time.Duration, prec int) string {

  s := in.String()

  ix := strings.IndexRune(s, '.')

  if ix == -1 {

    return s

  }

  unit:=len(s)

  for i,x:=range s[:ix+1] {

     if !unicode.IsDigit(x) {

       unit=i+ix+1

       break

     }

  }

  if prec == 0 {

     return s[:ix]+s[unit:]

  }

  if prec>len(s)-ix-(len(s)-unit)-1 {

     prec=len(s)-ix-(len(s)-unit)-1

  }

  return s[:ix+prec+1]+s[unit:]

}


func main() {

   ...

   fmt.Printf("%v\n", fmtTime(time.Since(started), 3))

}

或者您可以使用格式化程序定義新類型,并使用新類型進行打?。?/p>


type FmtDuration time.Duration


func (d FmtDuration) Format(f fmt.State, c rune) {

   prec,_ := f.Precision()

   f.Write([]byte(fmtTime(time.Duration(d), prec)))

}


func main() {

   fmt.Printf("%.2v", FmtDuration(time.Since(started)))

}


查看完整回答
反對 回復 2023-07-31
?
翻翻過去那場雪

TA貢獻2065條經驗 獲得超14個贊

如果您只關心有效的 3 位數字:


// FormatDuration formats a duration with a precision of 3 digits

// if it is less than 100s.

func FormatDuration(d time.Duration) string {

    scale := 100 * time.Second

    // look for the max scale that is smaller than d

    for scale > d {

        scale = scale / 10

    }

    return d.Round(scale / 100).String()

}


func Test_FormatDuration(t *testing.T) {

    for i := 0; i < 15; i++ {

        dur := time.Duration(3.455555 * math.Pow(10, float64(i)))

        t.Logf("%2d  %12v  %6s", i, dur,  FormatDuration(dur))

    }

}

//      original     formatted

//  0           3ns     3ns

//  1          34ns    34ns

//  2         345ns   345ns

//  3       3.455μs  3.46μs

//  4      34.555μs  34.6μs

//  5     345.555μs   346μs

//  6    3.455555ms  3.46ms

//  7    34.55555ms  34.6ms

//  8    345.5555ms   346ms

//  9     3.455555s   3.46s

// 10     34.55555s   34.6s

// 11    5m45.5555s   5m46s

// 12    57m35.555s  57m36s

// 13   9h35m55.55s  9h35m56s

// 14   95h59m15.5s  95h59m16s


查看完整回答
反對 回復 2023-07-31
  • 3 回答
  • 0 關注
  • 215 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號