Golang time包常用函数及其原理
- time.Now()函数:
type Time struct { wall uint64 ext int64 loc *Location } type Location struct { name string zone []zone tx []zoneTrans cacheStart int64 cacheEnd int64 cacheZone *zone } type zone struct { name string // abbreviated name, "CET" offset int // seconds east of UTC isDST bool // is this zone Daylight Savings Time? } type zoneTrans struct { when int64 // transition time, in seconds since 1970 GMT index uint8 // the index of the zone that goes into effect at that time isstd, isutc bool // ignored - no idea what these mean } func Now() Time { sec, nsec, mono := now() mono -= startNano sec += unixToInternal - minWall if uint64(sec)>>33 != 0 { return Time{uint64(nsec), sec + minWall, Local} } return Time{hasMonotonic | uint64(sec)<<nsecShift | uint64(nsec), mono, Local} } 返回格式 2019-08-08 10:52:22.6178113 +0800 CST m=+1.102525501 使用方式: 调用time.Now()函数接收返回值后可以对其做格式化输出,如: time.Now().Local()//2019-08-08 11:15:58.8441185 +0800 CST time.Now.Date()//2019 August 8 ... ```
- Golang计时器
func main(){
tric:=time.Tick(time.Second*2)
for {
select {
case v := <-tric:
fmt.Println(v)
}
}}//相关源代码:
func Tick(d Duration) <-chan Time {//返回一个只读的时间管道
if d <= 0 {
return nil
}
return NewTicker(d).C
}
type runtimeTimer struct {
tb uintptr
i int
when int64
period int64
f func(interface{}, uintptr) // NOTE: must not be closure
arg interface{}
seq uintptr
}
type Ticker struct {
C <-chan Time
r runtimeTimer
}
func NewTicker(d Duration) *Ticker {
if d <= 0 {
panic(errors.New("non-positive interval for NewTicker"))
}
// Give the channel a 1-element time buffer.
// If the client falls behind while reading, we drop ticks
// on the floor until the client catches up.
c := make(chan Time, 1)
t := &Ticker{
C: c,
r: runtimeTimer{
when: when(d),
period: int64(d),
f: sendTime,
arg: c,
},
}
startTimer(&t.r)//源代码中该函数仅是声明,这里实际是为了调用&t.r
return t
}```
从源代码可以看出Tick返回返回一个Ticker实例,
这里参数和返回值<-chan int 表示只读管道,不允许close()
chan <-int表示只写管道,允许Close()
简单的超时函数:
func waitTimer(ch <-chan int,du time.Duration)bool{//接收只读管道和超时时间
time:=time.NewTimer(du)//返回值.C是一个只读管道
select {
case <-ch:
return true
case <-time.C:
return false
}
}
对于通过case条件将程序编程延时执行或定时任务之类的
time.After(Duration):
该函数返回一个Timer.C,也就是<-chan time.Time,即返回一个定时器管道
ch:=time.After(time.Duration(1e9)):
select {
case <-ch
log.Println("delay")
}
time.AfterFunc(Duration,func)
该函数在指定计时时间到期后执行指定的func函数
内部实现事实上就是封装了一个计时器然后计时到期执行
Timer和Ticker结构定义是一样的,相关函数的实现也差不多,不过Timer的执行是一次性的而不像Ticker是定时触发
Ticker通过startTimer在系统协程中注册了一个事件,系统通过sendTime返回,在使用完计时器后应当手动close即Ticker.stop()
更多time库中的函数使用可以查看文档:https://studygol000000m/pkgdoc