Go_20: Golang 中 time 包的使用

time包中包括两类时间:时间点(某一时刻)和时常(某一段时间)

1. 时间常量(时间格式化)

const (
    ANSIC       = "Mon Jan _2 15:04:05 2006"
    UnixDate    = "Mon Jan _2 15:04:05 MST 2006"
    RubyDate    = "Mon Jan 02 15:04:05 -0700 2006"
    RFC822      = "02 Jan 06 15:04 MST"
    RFC822Z     = "02 Jan 06 15:04 -0700" // RFC822 with numeric zone
    RFC850      = "Monday, 02-Jan-06 15:04:05 MST"
    RFC1123     = "Mon, 02 Jan 2006 15:04:05 MST"
    RFC1123Z    = "Mon, 02 Jan 2006 15:04:05 -0700" // RFC1123 with numeric zone
    RFC3339     = "2006-01-02T15:04:05Z07:00"
    RFC3339Nano = "2006-01-02T15:04:05.999999999Z07:00"
    Kitchen     = "3:04PM"
    Stamp       = "Jan _2 15:04:05"
    StampMilli  = "Jan _2 15:04:05.000"
    StampMicro  = "Jan _2 15:04:05.000000"
    StampNano   = "Jan _2 15:04:05.000000000"
)

 这些常量是在time包中进行 time 格式化 和 time 解析而预定义的一些常量,其实他们使用的都是一个特定的时间:

  Mon Jan 2 15:04:05 MST 2006

这个时间是 Unix time 1136239445,因为MST是 GMT-0700,所以这个指定的时间也可以看做

  01/02 03:04:05PM '06 -0700

可见程序猿也有调皮的一面.

因此我们只需要利用上面这些时间变可以随意的指定自己的时间格式,例如:

layout := "01__02-2006 3.04.05 PM"
fmt.Println(time.Now().Format(layout))

便会输出类似的时间:11__26-2014 8.40.00 PM

2. 函数

1. time 组成

time.Duration(时间长度,消耗时间)
time.Time(时间点)
time.C(放时间的channel通道)(注:Time.C:=make(chan time.Time))

2. After 函数

func After(d Duration) <-chan Time
表示多少时间之后,但是在取出channel内容之前不阻塞,后续程序可以继续执行

func Sleep(d Duration)
表示休眠多少时间,休眠时处于阻塞状态,后续程序无法执行.

 举例说明二者区别:

fmt.Println("hello")
chan := time.After(time.Secone*1)
fmt.Println("World")
fmt.Println("hello")
chan := time.Sleep(time.Secone*1)
fmt.Println("World")

 第一个程序在执行完输出 hello 后,接着便输出 world,不用等待 1s,但是 1s 后,chan 中有数据,则会打印出来;

 第二个程序 chan 阻塞,则在输出 hello 后,程序变休眠 1s 中,然后才输出 World.

由此可见阻塞和非阻塞便是这两个函数的本质区别.

鉴于After特性,其通常用来处理程序超时问题,如下所示:

select {
case m := <-c:
    handle(m)
case <-time.After(5 * time.Minute):
    fmt.Println("timed out")
}

3. 重复执行的函数

func Tick(d Duration) <-chan Time

time.Tick(time.Duration) 用法和 time.After 差不多,但是它是表示每隔多少时间之后,是一个重复的过程,其他与 After 一致

type Ticker  //主要用来按照指定的时间周期来调用函数或者计算表达式,通常的使用方式是利用go新开一个协程使用,它是一个断续器
func NewTicker(d Duration) *Ticker    //新生成一个ticker,此Ticker包含一个channel,此channel以给定的duration发送时间。duration d必须大于0
func (t *Ticker) Stop()  //用于关闭相应的Ticker,但并不关闭channel

 使用时间控制停止ticker

ticker := time.NewTicker(time.Millisecond * 500)
go func() {
    for t := range ticker.C {
        fmt.Println("Tick at", t)
    }
}()

time.Sleep(time.Millisecond * 1500)   //阻塞,则执行次数为sleep的休眠时间/ticker的时间
ticker.Stop()     
fmt.Println("Ticker stopped")

 使用channel控制停止ticker

ticker := time.NewTicker(time.Millisecond * 500)
c := make(chan int,num) //num为指定的执行次数
go func() {
	for t := range ticker.C {
              c<-1
               fmt.Println("Tick at", t)
				
	}
}()
		
ticker.Stop()

 这种情况下,在执行 num 次以 Ticker 时间为单位的函数之后,c channel 中已满,以后便不会再执行对应的函数.

 

posted @ 2017-09-30 18:35  星火燎原智勇  阅读(1299)  评论(1编辑  收藏  举报