1. 程式人生 > 程式設計 >Golang中的time.Duration型別用法說明

Golang中的time.Duration型別用法說明

在 Time 包中,定義有一個名為 Duration 的型別和一些輔助的常量:

type Duration int64
 
const (
 Nanosecond Duration = 1
 Microsecond = 1000 * Nanosecond
 Millisecond = 1000 * Microsecond
 Second = 1000 * Millisecond
 Minute = 60 * Second
 Hour = 60 * Minute
)

那麼我們看下面一段程式碼:

func Test() {
 var waitFiveHundredMillisections int64 = 500
 
 startingTime := time.Now().UTC()
 time.Sleep(10 * time.Millisecond)
 endingTime := time.Now().UTC()
 
 var duration time.Duration = endingTime.Sub(startingTime)
 var durationAsInt64 = int64(duration)
 
 if durationAsInt64 >= waitFiveHundredMillisections {
 fmt.Printf("Time Elapsed : Wait[%d] Duration[%d]\n",waitFiveHundredMillisections,durationAsInt64)
 } else {
 fmt.Printf("Time DID NOT Elapsed : Wait[%d] Duration[%d]\n",durationAsInt64)
 }
}

以上程式碼執行後的輸出為:

Time Elapsed : Wait[500] Duration[10724798]

也就是說,定義的500毫秒已經用完了?當我們再次檢視Duration型別的定義,可以發現Duration型別彙總基本單位時間是納秒(Nanosecond),所以講一個表示10毫秒的Durantion型別物件轉換為int64型別時,實際上得到的是10,000,000。因此,直接轉換是不行的,需要一個不同的策略來使用和轉換Duration型別。

首先,我我們可以基於Duration中定義的常量,建立下面這樣的一個Duration變數:

func Test() {
 var duration_Milliseconds time.Duration = 500 * time.Millisecond
 var duration_Seconds time.Duration = (1250 * 10) * time.Millisecond
 var duration_Minute time.Duration = 2 * time.Minute
 
 fmt.Printf("Milli [%v]\nSeconds [%v]\nMinute [%v]\n",duration_Milliseconds,duration_Seconds,duration_Minute)
}

在上面程式碼中,我們建立了3個Duration型別的變數,通過使用時間常數,建立正確的持續時間值,然後使用標準庫函式Printf和%v操作符,得到下面的輸出結果:

Milli [500ms]
Seconds [12.5s]
Minute [2m0s]

Printf函式知道如何本地化顯示一個 Duration 型別,它基於 Duration 型別中的每一個值,選擇合適的格式進行時間的顯示。

實際上,Duration型別擁有一些邊界的型別轉換函式,他們能將Duration型別轉化為Go預研的內建型別int64或float64,例如:

func Test() {
 var duration_Seconds time.Duration = (1250 * 10) * time.Millisecond
 var duration_Minute time.Duration = 2 * time.Minute
 
 var float64_Seconds float64 = duration_Seconds.Seconds()
 var float64_Minutes float64 = duration_Minute.Minutes()
 
 fmt.Printf("Seconds [%.3f]\nMinutes [%.2f]\n",float64_Seconds,float64_Minutes)
}

需要注意的是,在時間轉換函式中,並沒有轉換毫秒值的函式,上述程式碼只使用 Seconds 和 Minutes 函式,得到了如下輸出:

Seconds [12.500]

Minutes [2.00]

當我們需要轉換毫秒值,但包裡面單單沒有提供毫秒值的裝換呢? Go 語言的設計者希望我有更多的選擇,而不只是將毫秒值轉換成某種單獨的內建型別。下面的程式碼中,我將毫秒值轉化為了 int64 型別和 float64 型別:

func Test() {
 var duration_Milliseconds time.Duration = 500 * time.Millisecond
 
 var castToInt64 int64 = duration_Milliseconds.Nanoseconds() / 1e6
 var castToFloat64 float64 = duration_Milliseconds.Seconds() * 1e3
 fmt.Printf("Duration [%v]\ncastToInt64 [%d]\ncastToFloat64 [%.0f]\n",castToInt64,castToFloat64)
}

我們將納秒值除以1e6得到了int64型別表示的毫秒值,將秒值乘以1e3,我們得到了float64型別表示的毫秒值,上面程式碼的輸出如下:

Duration [500ms]
castToInt64 [500]
castToFloat64 [500]

那麼,我們可以將最開始的測試程式碼修改如下:

func Test() {
 var waitFiveHundredMillisections time.Duration = 500 * time.Millisecond
 
 startingTime := time.Now().UTC()
 time.Sleep(600 * time.Millisecond)
 endingTime := time.Now().UTC()
 
 var duration time.Duration = endingTime.Sub(startingTime) 
 if duration >= waitFiveHundredMillisections {
 fmt.Printf("Wait %v\nNative [%v]\nMilliseconds [%d]\nSeconds [%.3f]\n",duration,duration.Nanoseconds()/1e6,duration.Seconds())
 }
}

得到輸出如下:

Wait 500ms
Native [601.091066ms]
Milliseconds [601]
Seconds [0.601]

補充:golang time.Duration 自定義變數報錯解決

對於time.Duration型別,如果採用 time.Duration型別 * int變數 會報錯,而直接和數字相乘則不會出現;

具體是為什麼呢?怎麼解決呢?

錯誤:

Invalid operation: time.Millisecond * idcTimeOut (mismatched types Duration and int64)

原因:因為型別不匹配,time.Duration型別 不能直接和 int型別相乘,需要先將變數轉換為time.Duration

解決方式:

time.Duration(int變數))

程式碼如下:

 idc := getIdc()
 var idcTimeOut int64
 if _,ok := IdcTimeout[idc]; ok {
 idcTimeOut = IdcTimeout[idc]
 } else {
 idcTimeOut = AllTimeout
 }
 
 //錯誤寫法
 time.After(time.Millisecond * idcTimeOut
 //正確寫法
 time.After(time.Millisecond * time.Duration(idcTimeOut))

以上為個人經驗,希望能給大家一個參考,也希望大家多多支援我們。如有錯誤或未考慮完全的地方,望不吝賜教。