在我们编程过程中,经常会用到与时间相关的各种务需求,下面来介绍golang中有关时间的一些基本用法,我们从time的几种type来开始介绍。
时间可分为时间点与时间段,golang也不例外,提供了以下两种基础类型
-时间点(Time)
-时间段(Duration)除此之外golang也提供了以下类型,做一些特定的业务
-时区(Location)
-Ticker
-Timer(定时器)我们将按以上顺序来介绍time包的使用。
我们使用的所有与时间相关的业务都是基于点而延伸的,两点组成一个时间段,大多数应用也都是围绕这些点与面去做逻辑处理。
go针对不同的参数类型提供了以下初始化的方式
//funcNow()Time fmt.Println(time.Now()) //funcParse(layout,valuestring)(Time,error) time.Parse("2016-01-0215:04:05","2018-04-2312:24:51") //funcParseInLocation(layout,valuestring,loc*Location)(Time,error)(layout已带时区时可直接用Parse) time.ParseInLocation("2006-01-0215:04:05","2017-05-1114:06:06",time.Local) //funcUnix(secint64,nsecint64)Time time.Unix(1e9,0) //funcDate(yearint,monthMonth,day,hour,min,sec,nsecint,loc*Location)Time time.Date(2018,1,2,15,30,10,0,time.Local) //func(tTime)In(loc*Location)Time当前时间对应指定时区的时间 loc,_:=time.LoadLocation("America/Los_Angeles") fmt.Println(time.Now().In(loc)) //func(tTime)Local()Time获取到时间点之后为了满足业务和设计,需要转换成我们需要的格式,也就是所谓的时间格式化。
格式化为字符串我们需要使用time.Format方法来转换成我们想要的格式
fmt.Println(time.Now().Format("2006-01-0215:04:05"))//2018-04-2410:11:20 fmt.Println(time.Now().Format(time.UnixDate))//TueApr2409:59:02CST2018Format函数中可以指定你想使用的格式,同时time包中也给了一些我们常用的格式
const( ANSIC="MonJan_215:04:052006" UnixDate="MonJan_215:04:05MST2006" RubyDate="MonJan0215:04:05-07002006" RFC822="02Jan0615:04MST" RFC822Z="02Jan0615:04-0700"//RFC822withnumericzone RFC850="Monday,02-Jan-0615:04:05MST" RFC1123="Mon,02Jan200615:04:05MST" RFC1123Z="Mon,02Jan200615:04:05-0700"//RFC1123withnumericzone RFC3339="2006-01-02T15:04:05Z07:00" RFC3339Nano="2006-01-02T15:04:05.999999999Z07:00" Kitchen="3:04PM" //Handytimestamps. Stamp="Jan_215:04:05" StampMilli="Jan_215:04:05.000" StampMicro="Jan_215:04:05.000000" StampNano="Jan_215:04:05.000000000" )注意:galang中指定的特定时间格式为"2006-01-0215:04:05-0700MST",为了记忆方便,按照美式时间格式月日时分秒年外加时区排列起来依次是01/0203:04:05PM‘06-0700,刚开始使用时需要注意。
totimestamp func(tTime)Unix()int64 func(tTime)UnixNano()int64 fmt.Println(time.Now().Unix()) //获取指定日期的时间戳 dt,_:=time.Parse("2016-01-0215:04:05","2018-04-2312:24:51") fmt.Println(dt.Unix()) fmt.Println(time.Date(2018,1,2,15,30,10,0,time.Local).Unix()) 其他time包还提供了一些常用的方法,基本覆盖了大多数业务,从方法名就能知道代表的含义就不一一说明了。
func(tTime)Date()(yearint,monthMonth,dayint) func(tTime)Clock()(hour,min,secint) func(tTime)Year()int func(tTime)Month()Month func(tTime)Day()int func(tTime)Hour()int func(tTime)Minute()int func(tTime)Second()int func(tTime)Nanosecond()int func(tTime)YearDay()int func(tTime)Weekday()Weekday func(tTime)ISOWeek()(year,weekint) func(tTime)IsZero()bool func(tTime)Local()Time func(tTime)Location()*Location func(tTime)Zone()(namestring,offsetint) func(tTime)Unix()int64介绍完了时间点,我们再来介绍时间段,即Duartion类型,我们业务也是很常用的类型。
//funcParseDuration(sstring)(Duration,error) tp,_:=time.ParseDuration("1.5s") fmt.Println(tp.Truncate(1000),tp.Seconds(),tp.Nanoseconds()) func(dDuration)Hours()float64 func(dDuration)Minutes()float64 func(dDuration)Seconds()float64 func(dDuration)Nanoseconds()int64 func(dDuration)Round(mDuration)Duration//四舍五入 func(dDuration)Truncate(mDuration)Duration//向下取整我们在来介绍一下时区的相关的函数
//默认UTC loc,err:=time.LoadLocation("") //服务器设定的时区,一般为CST loc,err:=time.LoadLocation("Local") //美国洛杉矶PDT loc,err:=time.LoadLocation("America/Los_Angeles") //获取指定时区的时间点 local,_:=time.LoadLocation("America/Los_Angeles") fmt.Println(time.Date(2018,1,1,12,0,0,0,local))可以在$GOROOT/lib/time/zoneinfo.zip文件下看到所有时区。
好了,基础的类型我们介绍完,现在开始时间运算相关的函数,也是日常业务中我们大量应用的。
//funcSleep(dDuration)休眠多少时间,休眠时处于阻塞状态,后续程序无法执行 time.Sleep(time.Duration(10)*time.Second) //funcAfter(dDuration)<-chanTime非阻塞,可用于延迟 time.After(time.Duration(10)*time.Second) //funcSince(tTime)Duration两个时间点的间隔 start:=time.Now() fmt.Println(time.Since(start))//等价于Now().Sub(t),可用来计算一段业务的消耗时间 funcUntil(tTime)Duration//等价于t.Sub(Now()),t与当前时间的间隔 //func(tTime)Add(dDuration)Time fmt.Println(dt.Add(time.Duration(10)*time.Second))//加 func(tTime)Sub(uTime)Duration//减 //func(tTime)AddDate(yearsint,monthsint,daysint)Time fmt.Println(dt.AddDate(1,1,1)) //func(tTime)Before(uTime)bool //func(tTime)After(uTime)bool //func(tTime)Equal(uTime)bool比较时间点时尽量使用Equal函数我们大概就介绍完了多数涉及时间点与时间段的函数,接下面我们通过一些使用场景来做一些演示。
通过time.After函数与select结合使用可用于处理程序超时设定
select{ casem:=<-c: //dosomething case<-time.After(time.Duration(1)*time.Second): fmt.Println("timeout") }Ticker类型包含一个channel,有时我们会遇到每隔一段时间执行的业务(比如设置心跳时间等),就可以用它来处理,这是一个重复的过程
//无法取消 tick:=time.Tick(1*time.Minute) for_=rangetick{ //dosomething } //可通过调用ticker.Stop取消 ticker:=time.NewTicker(1*time.Minute) for_=rangetick{ //dosomething }Timer类型用来代表一个单独的事件,当设置的时间过期后,发送当前的时间到channel,我们可以通过以下两种方式来创建
funcAfterFunc(dDuration,ffunc())*Timer//指定一段时间后指定的函数 funcNewTimer(dDuration)*Timer以上两函数都可以使用Reset,这个有个需要注意的地方是使用Reset时需要确保t.C通道被释放时才能调用,以防止发生资源竞争的问题,可通过以下方式解决
if!t.Stop(){ <-t.C } t.Reset(d)packagetime
golang积累-时间、时区、格式的使用
论golangTimerReset方法使用的正确姿势
本文内容总结:时间点(Time),初始化,格式化,时间段(Duartion),时区(Location),时间运算,使用场景,日期时间差,基于当前时间的前后运算,时区转换,比较两个时间点,设置执行时间,Ticker类型,Timer类型,参考文献,
原文链接:https://www.cnblogs.com/sandea/p/9696712.html