Go语言_时间篇


Go的time包是标准库中的包之一

不用说,几乎是开发必须用到的包之一。time包的说明文档在:

http://golang.org/pkg/time/

 

先注意下Overview中的一句话:

The calendrical calculations always assume a Gregorian calendar.

这个包的时间计算式是基于格里历,就是我们使用的公历。关于格里历的历史,可以看百度百科:

http://baike.baidu.com/view/391054.htm

 

看看godoc文档,最大的数据类型就是Time了,这个Time类型最微小可以表示到nanosecond(微毫秒,十亿份之一秒)。

clip_image001

 

Time的比较是使用Before,After和Equal方法。看一眼After:

func (t Time) After(u Time) bool

很好,返回的是bool类型,是我们所需要的。

 

Sub方法返回的是两个时间点之间的时间距离,看上图看到它返回的是Duration结构,这个结构的具体类型和操作也在godoc中

 

Add方法和Sub方法是相反的,获取t0和t1的时间距离d是使用Sub,将t0加d获取t1就是使用Add方法

 

IsZero方法:Time的zero时间点是January 1, year 1, 00:00:00 UTC,这个函数判断一个时间是否是zero时间点

 

Local,UTC,Ln是用来显示和计算地区时间的。

 

下面从几个需求直接看time的使用

1 请打出当前时间的时间戳,然后将时间戳格式为年月日时分秒的形式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package  main
 
import  (
     "fmt"
     "time"
)
 
func main() {
     //时间戳
     t := time.Now().Unix()
     fmt.Println(t)
     
     //时间戳到具体显示的转化
     fmt.Println(time.Unix(t, 0 ).String())
     
     //带纳秒的时间戳
     t = time.Now().UnixNano()
     fmt.Println(t)
     fmt.Println( "------------------" )
     
     //基本格式化的时间表示
     fmt.Println(time.Now().String())
     
     fmt.Println(time.Now().Format( "2006year 01month 02day" ))
 
}

显示:

clip_image002

特别是Format这个函数,可以好好使用

2 输出当前星期几?

1
2
3
4
5
6
7
8
9
10
11
12
13
package  main
 
import  (
     "fmt"
     "time"
)
 
func main() {
     //时间戳
     t := time.Now()
     fmt.Println(t.Weekday().String())
 
}

clip_image003

 

文档中对这个Weekday类型就没有说明!!没法,直接看代码可以看到:

clip_image004

 

Weekday有一个String()方法

好了,看到这里外带我们有一个推测:

 

当一个结构中有定义String()函数的时候,fmt.Println()是会调用String的

例子如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package  main
 
import  (
     "fmt"
)
 
type MyStruct struct{
}
 
func (d MyStruct)String() string { return  "mystruct" }
 
func main() {
     me := new (MyStruct)
     fmt.Println(me)
 
}

clip_image005

 

Go的Time之旅结束!!

go语言的time包

组成

  • time.Duration(时长,耗时)
  • time.Time(时间点)
  • time.C(放时间点的管道)[ Time.C:=make(chan time.Time) ]

time包里有2个东西,一个是时间点,另一个是时长
时间点的意思就是“某一刻”,比如 2000年1月1日1点1分1秒 那一刻(后台记录的是unix时间,从1970年开始计算)
时长就是某一刻与另一刻的差,也就是耗时

函数

Sleep函数

time.Sleep(time.Duration)
表示睡多少时间,睡觉时,是阻塞状态

fmt.Println("start sleeping...") time.Sleep(time.Second) fmt.Println("end sleep.") //【结果】打印start sleeping后,等了正好1秒后,打印了end sleep //会阻塞,Sleep时,什么事情都不会做 

time.sleep

After函数

time.After(time.Duration)
和Sleep差不多,意思是多少时间之后,但在取出管道内容前不阻塞

fmt.Println("the 1") tc:=time.After(time.Second) //返回一个time.C这个管道,1秒(time.Second)后会在此管道中放入一个时间点(time.Now()) //时间点记录的是放入管道那一刻的时间值 fmt.Println("the 2") fmt.Println("the 3") <-tc //阻塞中,直到取出tc管道里的数据 fmt.Println("the 4") //【结果】立即打印123,等了1秒不到一点点的时间,打印了4,结束 //打印the 1后,获得了一个空管道,这个管道1秒后会有数据进来 //打印the 2,(这里可以做更多事情) //打印the 3 //等待,直到可以取出管道的数据(取出数据的时间与获得tc管道的时间正好差1秒钟) //打印the 4 

time.After1

fmt.Println("the 1") tc:=time.After(time.Second * 2) //返回一个time.C这个管道,2秒(time.Second × 2)后会在此管道中放入 //一个时间点(time.Now()),时间点记录的是放入管道那一刻的时间值 fmt.Println("the 2") fmt.Println("the 3") time.Sleep(time.Second)//这里是假设这个Println动作执行了半秒钟 fmt.Println("the 4") time.Sleep(time.Second)//这里是假设这个Println动作执行了半秒钟 fmt.Println("the 5") fmt.Println("the 6") fmt.Println("the 7") <-tc //阻塞中,直到取出tc管道里的数据 fmt.Println("the 8") //【结果】立即打印1和2和3,等了1秒打印了4,打完后又等了1秒打印了5,然后又立即打印了678,结束 //这里的<-tc是立即能获得数据的 //因为早在执行差不多Print 5的时候,管道内已经有数据了 //当gorotine线把数据丢到管道中后,它自己阻塞了(具体请了解goroutine) 

time.After2

AfterFunc函数

time.AfterFunc(time.Duration,func())
和After差不多,意思是多少时间之后在goroutine line执行函数

f := func() { fmt.Println("Time out") } time.AfterFunc(1*time.Second, f) time.Sleep(2 * time.Second) //要保证主线比子线“死的晚”,否则主线死了,子线也等于死了 //【结果】运行了1秒后,打印出timeout,又过了1秒,程序退出 //将一个间隔和一个函数给AfterFunc后 //间隔时间过后,执行传入的函数 

time.AfterFunc

由于f函数不是在Main Line执行的,而是注册在goroutine Line里执行的
所以一旦后悔的话,需要使用Stop命令来停止即将开始的执行,如果已经开始执行就来不及了

houhui := true f := func() { fmt.Println("Time out") } ta := time.AfterFunc(2*time.Second, f) time.Sleep(time.Second) if houhui { ta.Stop() } time.Sleep(3 * time.Second) //要保证主线比子线“死的晚”,否则主线死了,子线也等于死了 //【结果】运行了3秒多一点点后,程序退出,什么都不打印 //注册了个f函数,打算2秒后执行 //过了1秒后,后悔了,停掉(Stop)它 

Tick函数

time.Tick(time.Duration)
和After差不多,意思是每隔多少时间后,其他与After一致

fmt.Println("the 1") tc:=time.Tick(time.Second) //返回一个time.C这个管道,1秒(time.Second)后会在此管道中放入一个时间点, //1秒后再放一个,一直反复,时间点记录的是放入管道那一刻的时间 for i:=1;i<=2;i++{ <-tc fmt.Println("hello") } //每隔1秒,打印一个hello 

time.Tick

time.Time的方法(time.Time自己独有的函数)

Before & After方法

判断一个时间点是否在另一个时间点的前面(后面),返回true或false

t1:=time.Now() time.Sleep(time.Second) t2:=time.Now() a:=t2.After(t1) //t2的记录时间是否在t1记录时间的**后面**呢,是的话,a就是true fmt.Println(a) //true b:=t2.Before(t1) //t2的记录时间是否在t1记录时间的**前面**呢,是的话,b就是true fmt.Println(b) //false 

Sub方法

两个时间点相减,获得时间差(Duration)

t1:=time.Now() time.Sleep(time.Second) t2:=time.Now() d:=t2.Sub(t1) //时间2减去时间1 fmt.Println(d) //打印结果差不多为1.000123几秒,因为Sleep无法做到精确的睡1秒 后发生的时间 减去 先发生时间,是正数 

Add方法

拿一个时间点,add一个时长,获得另一个时间点

t1:=time.Now() //现在是12点整(假设),那t1记录的就是12点整 t2:=t1.Add(time.Hour) //那t1的时间点 **加上(Add)** 1个小时,是几点呢? fmt.Println(t2) //13点(呵呵)


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM