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