Golang中的time.Duration类型用法说明
在Time包中,定义有一个名为Duration的类型和一些辅助的常量:
typeDurationint64 const( NanosecondDuration=1 Microsecond=1000*Nanosecond Millisecond=1000*Microsecond Second=1000*Millisecond Minute=60*Second Hour=60*Minute )
那么我们看下面一段代码:
funcTest(){ varwaitFiveHundredMillisectionsint64=500 startingTime:=time.Now().UTC() time.Sleep(10*time.Millisecond) endingTime:=time.Now().UTC() vardurationtime.Duration=endingTime.Sub(startingTime) vardurationAsInt64=int64(duration) ifdurationAsInt64>=waitFiveHundredMillisections{ fmt.Printf("TimeElapsed:Wait[%d]Duration[%d]\n",waitFiveHundredMillisections,durationAsInt64) }else{ fmt.Printf("TimeDIDNOTElapsed:Wait[%d]Duration[%d]\n",waitFiveHundredMillisections,durationAsInt64) } }
以上代码运行后的输出为:
TimeElapsed:Wait[500]Duration[10724798]
也就是说,定义的500毫秒已经用完了?当我们再次查看Duration类型的定义,可以发现Duration类型汇总基本单位时间是纳秒(Nanosecond),所以讲一个表示10毫秒的Durantion类型对象转换为int64类型时,实际上得到的是10,000,000。因此,直接转换是不行的,需要一个不同的策略来使用和转换Duration类型。
首先,我我们可以基于Duration中定义的常量,创建下面这样的一个Duration变量:
funcTest(){ varduration_Millisecondstime.Duration=500*time.Millisecond varduration_Secondstime.Duration=(1250*10)*time.Millisecond varduration_Minutetime.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,例如:
funcTest(){ varduration_Secondstime.Duration=(1250*10)*time.Millisecond varduration_Minutetime.Duration=2*time.Minute varfloat64_Secondsfloat64=duration_Seconds.Seconds() varfloat64_Minutesfloat64=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类型:
funcTest(){ varduration_Millisecondstime.Duration=500*time.Millisecond varcastToInt64int64=duration_Milliseconds.Nanoseconds()/1e6 varcastToFloat64float64=duration_Milliseconds.Seconds()*1e3 fmt.Printf("Duration[%v]\ncastToInt64[%d]\ncastToFloat64[%.0f]\n",duration_Milliseconds,castToInt64,castToFloat64) }
我们将纳秒值除以1e6得到了int64类型表示的毫秒值,将秒值乘以1e3,我们得到了float64类型表示的毫秒值,上面代码的输出如下:
Duration[500ms] castToInt64[500] castToFloat64[500]
那么,我们可以将最开始的测试代码修改如下:
funcTest(){ varwaitFiveHundredMillisectionstime.Duration=500*time.Millisecond startingTime:=time.Now().UTC() time.Sleep(600*time.Millisecond) endingTime:=time.Now().UTC() vardurationtime.Duration=endingTime.Sub(startingTime) ifduration>=waitFiveHundredMillisections{ fmt.Printf("Wait%v\nNative[%v]\nMilliseconds[%d]\nSeconds[%.3f]\n",waitFiveHundredMillisections,duration,duration.Nanoseconds()/1e6,duration.Seconds()) } }
得到输出如下:
Wait500ms Native[601.091066ms] Milliseconds[601] Seconds[0.601]
补充:golangtime.Duration自定义变量报错解决
对于time.Duration类型,如果采用time.Duration类型*int变量会报错,而直接和数字相乘则不会出现;
具体是为什么呢?怎么解决呢?
错误:
Invalidoperation:time.Millisecond*idcTimeOut(mismatchedtypesDurationandint64)
原因:因为类型不匹配,time.Duration类型不能直接和int类型相乘,需要先将变量转换为time.Duration
解决方式:
time.Duration(int变量))
代码如下:
idc:=getIdc() varidcTimeOutint64 if_,ok:=IdcTimeout[idc];ok{ idcTimeOut=IdcTimeout[idc] }else{ idcTimeOut=AllTimeout } //错误写法 time.After(time.Millisecond*idcTimeOut //正确写法 time.After(time.Millisecond*time.Duration(idcTimeOut))
以上为个人经验,希望能给大家一个参考,也希望大家多多支持毛票票。如有错误或未考虑完全的地方,望不吝赐教。