Go的time包是標准庫中的包之一
不用說,幾乎是開發必須用到的包之一。time包的說明文檔在:
先注意下Overview中的一句話:
The calendrical calculations always assume a Gregorian calendar.
這個包的時間計算式是基於格里歷,就是我們使用的公歷。關於格里歷的歷史,可以看百度百科:
http://baike.baidu.com/view/391054.htm
看看godoc文檔,最大的數據類型就是Time了,這個Time類型最微小可以表示到nanosecond(微毫秒,十億份之一秒)。
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"
))
}
|
顯示:
特別是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())
}
|
文檔中對這個Weekday類型就沒有說明!!沒法,直接看代碼可以看到:
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)
}
|
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時,什么事情都不會做
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
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)
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后 //間隔時間過后,執行傳入的函數
由於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.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點(呵呵)