Golang time库

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值