首页 文章资讯内容详情

golang包time用法详解

2026-06-01 4 花语

本文内容纲要:

-时间点(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