golang package time的用法具体详解
在我们编程过程中,经常会用到与时间相关的各种务需求,下面来介绍golang中有关时间的一些基本用法,我们从time的几种type来开始介绍。
时间可分为时间点与时间段,golang也不例外,提供了以下两种基础类型
- 时间点(Time)
- 时间段(Duration)
除此之外golang也提供了以下类型,做一些特定的业务
- 时区(Location)
- Ticker
- Timer(定时器)
我们将按以上顺序来介绍time包的使用。
时间点(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
获取到时间点之后为了满足业务和设计,需要转换成我们需要的格式,也就是所谓的时间格式化。
格式化
tostring
格式化为字符串我们需要使用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:02CST2018
Format函数中可以指定你想使用的格式,同时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)
介绍完了时间点,我们再来介绍时间段,即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//向下取整
时区(Location)
我们在来介绍一下时区的相关的函数
//默认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函数
我们大概就介绍完了多数涉及时间点与时间段的函数,接下面我们通过一些使用场景来做一些演示。
使用场景
日期时间差
dt1:=time.Date(2018,1,10,0,0,1,100,time.Local) dt2:=time.Date(2018,1,9,23,59,22,100,time.Local) //不用关注时区,go会转换成时间戳进行计算 fmt.Println(dt1.Sub(dt2))
基于当前时间的前后运算
now:=time.Now() //一年零一个月一天之后 fmt.Println(now.Date(1,1,1)) //一段时间之后 fmt.Println(now.Add(time.Duration(10)*time.Minute)) //计算两个时间点的相差天数 dt1=time.Date(dt1.Year(),dt1.Month(),dt1.Day(),0,0,0,0,time.Local) dt2=time.Date(dt2.Year(),dt2.Month(),dt2.Day(),0,0,0,0,time.Local) fmt.Println(int(math.Ceil(dt1.Sub(dt2).Hours()/24)))
时区转换
//time.Local用来表示当前服务器时区 //自定义地区时间 secondsEastOfUTC:=int((8*time.Hour).Seconds()) beijing:=time.FixedZone("BeijingTime",secondsEastOfUTC) fmt.Println(time.Date(2018,1,2,0,0,0,0,beijing))//2018-01-0200:00:00+0800BeijingTime //当前时间转为指定时区时间 fmt.Println(time.Now().In(beijing)) //指定时间转换成指定时区对应的时间 dt,err:=time.ParseInLocation("2006-01-0215:04:05","2017-05-1114:06:06",time.Local) //当前时间在零时区年月日时分秒时区 year,mon,day:=time.Now().UTC().Date()//2018April24 hour,min,sec:=time.Now().UTC().Clock()//34715 zone,_:=time.Now().UTC().Zone()//UTC
比较两个时间点
dt:=time.Date(2018,1,10,0,0,1,100,time.Local) fmt.Println(time.Now().After(dt))//true fmt.Println(time.Now().Before(dt))//false //是否相等判断两个时间点是否相等时推荐使用Equal函数 fmt.Println(dt.Equal(time.Now()))
设置执行时间
通过time.After函数与select结合使用可用于处理程序超时设定
select{ casem:=<-c: //dosomething case<-time.After(time.Duration(1)*time.Second): fmt.Println("timeout") }
Ticker类型
Ticker类型包含一个channel,有时我们会遇到每隔一段时间执行的业务(比如设置心跳时间等),就可以用它来处理,这是一个重复的过程
//无法取消 tick:=time.Tick(1*time.Minute) for_=rangetick{ //dosomething } //可通过调用ticker.Stop取消 ticker:=time.NewTicker(1*time.Minute) for_=rangetick{ //dosomething }
Timer类型
Timer类型用来代表一个单独的事件,当设置的时间过期后,发送当前的时间到channel,我们可以通过以下两种方式来创建
funcAfterFunc(dDuration,ffunc())*Timer//指定一段时间后指定的函数 funcNewTimer(dDuration)*Timer
以上两函数都可以使用Reset,这个有个需要注意的地方是使用Reset时需要确保t.C通道被释放时才能调用,以防止发生资源竞争的问题,可通过以下方式解决
if!t.Stop(){ <-t.C } t.Reset(d)
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。