golang包time用法详解
本文内容纲要:
-时间点(Time)
-初始化
-格式化
-时间段(Duartion)
-时区(Location)
-时间运算
-使用场景
-日期时间差
-基于当前时间的前后运算
-时区转换
-比较两个时间点
-设置执行时间
-Ticker类型
-Timer类型
-参考文献
在我们编程过程中,经常会用到与时间相关的各种务需求,下面来介绍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
比较两个时间点
//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
设置执行时间
通过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)
参考文献
packagetime
golang积累-时间、时区、格式的使用
论golangTimerReset方法使用的正确姿势
本文内容总结:时间点(Time),初始化,格式化,时间段(Duartion),时区(Location),时间运算,使用场景,日期时间差,基于当前时间的前后运算,时区转换,比较两个时间点,设置执行时间,Ticker类型,Timer类型,参考文献,
原文链接:https://www.cnblogs.com/sandea/p/9696712.html