作者:尹正傑
版權宣告:原創作品,謝絕轉載!否則將追究法律責任。
目錄
- 一.時間型別
- 二.Location和time zone
- 1.時區介紹
- 2.時區案例
- 三.時間戳unix time
- 1.Unix Time概述
- 2.獲取時間戳
- 3.將時間戳轉為時間物件
- 四.時間間隔設定及比較
- 1.時間間隔型別的常量
- 2.Add
- 3.sub
- 4.Equal
- 5.Before
- 6.After
- 五.定時器
- 1.定時器概述
- 2.定時器案例
- 六.時間格式化
- 1.時間格式化
- 2.參考案例
- 七.解析字串的時間
- 1.解析時間的函式
- 2.Parse從文字解析時間
- 3.ParseInLocation從文字解析時間
- 八.練習題
- 1.獲取當前時間,格式化輸出為"2030/01/01 23:30:05"格式
- 2.編寫程式統計一段程式碼的執行耗時時間,單位精確到微秒。
一.時間型別
package main
import (
"time"
"fmt"
)
func main() {
// 獲取當前時間物件,後從時間物件中可以獲取到年、月、日、時、分、秒等資訊。
now := time.Now()
fmt.Printf("current time: [%v]\n", now)
// 年
year := now.Year()
// 月
month := now.Month()
// 日
day := now.Day()
// 小時
hour := now.Hour()
// 分鐘
minute := now.Minute()
// 秒
second := now.Second()
fmt.Println(year, month, day, hour, minute, second)
}
二.Location和time zone
1.時區介紹
Go語言中使用location來對映具體的時區。時區(Time Zone)是根據世界各國家與地區不同的經度而劃分的時間定義,全球共分為24個時區。
中國差不多跨5個時區,但為了使用方便只用東八時區的標準時即北京時間為準。在日常編碼過程中使用時間物件的時候一定要注意其時區資訊。
2.時區案例
package main
import (
"fmt"
"time"
)
func main() {
// 中國沒有夏令時,使用一個固定的8小時的UTC時差(東八區,UTC +08:00),對於很多其他國家需要考慮夏令時。
timezone := int((8 * time.Hour).Seconds())
// FixedZone 返回始終使用給定區域名稱和偏移量(UTC 以東秒)的Location。UTC +08:00
shanghaiTimezone := time.FixedZone("Asia/Shanghai", timezone)
// 如果當前系統有時區資料庫,則可以載入一個位置得到對應的時區,例如,載入紐約所在的時區,UTC -05:00
newYorkTimezone, _ := time.LoadLocation("America/New_York")
utc := time.Date(2009, 1, 1, 12, 0, 0, 0, time.UTC)
shanghai := time.Date(2009, 1, 1, 20, 0, 0, 0, shanghaiTimezone)
NewYork := time.Date(2009, 1, 1, 7, 0, 0, 0, newYorkTimezone)
// 北京時間(東八區)比UTC早8小時,所以上面兩個時間看似差了8小時,但表示的是同一個時間
t1 := utc.Equal(shanghai)
// 紐約(西五區)比UTC晚5小時,所以上面兩個時間看似差了5小時,但表示的是同一個時間
t2 := utc.Equal(NewYork)
fmt.Printf("[%v] = [%v] => [%t]\n",utc,shanghai,t1)
fmt.Printf("[%v] = [%v] => [%t]\n",utc,NewYork,t2)
}
三.時間戳unix time
1.Unix Time概述
Unix Time是自1970年1月1日 00:00:00 UTC至當前時間經過的總秒數。下面的程式碼片段演示瞭如何基於時間物件獲取到Unix 時間。
2.獲取時間戳
package main
import (
"fmt"
"time"
)
func main() {
// 獲取當前時間
now := time.Now()
// 秒級時間戳
timestamp := now.Unix()
// 毫秒時間戳 Go1.17+
milli := now.UnixMilli()
// 微秒時間戳 Go1.17+
micro := now.UnixMicro()
// 納秒時間戳
nano := now.UnixNano()
fmt.Printf("秒級時間戳: %v\n毫級時間戳: %v\n微級時間戳: %v\n納級時間戳: %v\n", timestamp, milli, micro, nano)
}
3.將時間戳轉為時間物件
package main
import (
"fmt"
"time"
)
func main() {
// 獲取北京時間所在的東八區時區物件
secondsEastOfUTC := int((8 * time.Hour).Seconds())
beijing := time.FixedZone("Beijing Time", secondsEastOfUTC)
// 北京時間 2022-02-22 22:22:22.000000022 +0800 CST
t := time.Date(2030, 11, 11, 23, 59, 59, 59, beijing)
var (
sec = t.Unix()
msec = t.UnixMilli()
usec = t.UnixMicro()
)
// 將秒級時間戳轉為時間物件(第二個引數為不足1秒的納秒數)
t1 := time.Unix(sec, 99999)
// 毫秒級時間戳轉為時間物件
t2 := time.UnixMilli(msec)
// 微秒級時間戳轉為時間物件
t3 := time.UnixMicro(usec)
fmt.Printf("t1 = [%v], t2 = [%v], t3 = [%v]\n", t1, t2, t3)
}
四.時間間隔設定及比較
1.時間間隔型別的常量
time.Duration是time包定義的一個型別,它代表兩個時間點之間經過的時間,以納秒為單位。
time.Duration表示一段時間間隔,可表示的最長時間段大約290年。
time包中定義的時間間隔型別的常量如下:
const (
Nanosecond Duration = 1
Microsecond = 1000 * Nanosecond
Millisecond = 1000 * Microsecond
Second = 1000 * Millisecond
Minute = 60 * Second
Hour = 60 * Minute
)
例如:time.Duration表示1納秒,time.Second表示1秒。
2.Add
package main
import (
"fmt"
"time"
)
func main() {
now := time.Now()
/*
Go語言的時間物件有提供Add方法如下:
func (t Time) Add(d Duration) Time
*/
later := now.Add(time.Hour) // 當前時間加1小時後的時間
fmt.Printf("now = [%v] later = [%v]\n", now, later)
}
3.sub
package main
import (
"fmt"
"time"
)
func main() {
now := time.Now()
t1, _ := time.Parse("2006/01/02 15:04:05", "2024/08/20 11:25:20")
/*
Go語言的時間物件有提供Sub方法如下:
func (t Time) Sub(u Time) Duration
*/
t2 := now.Sub(t1) // 比較現在和t1時間相差的時間
fmt.Printf("now = [%v] t2 = [%v]\n", now, t2)
}
4.Equal
package main
import (
"fmt"
"time"
)
func main() {
t1, _ := time.Parse("2006/01/02 15:04:05", "2030/08/20 11:25:20")
t2, _ := time.Parse(time.RFC3339, "2030-08-20T19:25:20+08:00")
/*
Go語言的時間物件有提供Equal方法如下:
func (t Time) Equal(u Time) bool
判斷兩個時間是否相同,會考慮時區的影響,因此不同時區標準的時間也可以正確比較。
本方法和用t==u不同,這種方法還會比較地點和時區資訊。
*/
flag := t1.Equal(t2)
fmt.Printf("[%v] = [%v] ---> [%t]\n", t1, t2, flag)
}
5.Before
package main
import (
"fmt"
"time"
)
func main() {
t1, _ := time.Parse("2006/01/02 15:04:05", "2030/08/21 12:25:20")
t2, _ := time.Parse(time.RFC3339, "2030-08-30T19:25:20+08:00")
/*
Go語言的時間物件有提供Before方法如下:
func (t Time) Before(u Time) bool
如果t代表的時間點在u之前,返回真;否則返回假。
*/
flag := t1.Before(t2)
fmt.Printf("[%v] = [%v] ---> [%t]\n", t1, t2, flag)
}
6.After
package main
import (
"fmt"
"time"
)
func main() {
t1, _ := time.Parse("2006/01/02 15:04:05", "2030/09/21 12:25:20")
t2, _ := time.Parse(time.RFC3339, "2030-08-30T19:25:20+08:00")
/*
Go語言的時間物件有提供Before方法如下:
func (t Time) After(u Time) bool
如果t代表的時間點在u之後,返回真;否則返回假。
*/
flag := t1.After(t2)
fmt.Printf("[%v] = [%v] ---> [%t]\n", t1, t2, flag)
}
五.定時器
1.定時器概述
使用time.Tick(時間間隔)來設定定時器,定時器的本質上是一個通道(channel)。
2.定時器案例
package main
import (
"fmt"
"time"
)
func main() {
// //定義一個1秒間隔的定時器,如果想要換成每分鐘,可以使用"time.Minute",依此類推...
ticker := time.Tick(time.Second)
for i := range ticker {
//每秒都會執行的任務
fmt.Println(i)
}
}
六.時間格式化
1.時間格式化
time.Format函式能夠將一個時間物件格式化輸出為指定佈局的文字表示形式,需要注意的是Go語言中時間格式化的佈局不是常見的Y-m-d H:M:S,而是使用"2006-01-02 15:04:05.000"(記憶口訣為2006 1 2 3 4 5)。
其中:
- 2006:年(Y)
- 01:月(m)
- 02:日(d)
- 15:時(H)
- 04:分(M)
- 05:秒(S)
溫馨提示:
(1)如果想格式化為12小時格式,需在格式化佈局中新增PM。
(2)小數部分想保留指定位數就寫0,如果想省略末尾可能的0就寫9。
2.參考案例
package main
import (
"fmt"
"time"
)
func main() {
// 獲取當前時間物件,後續方便基於對時間物件進行格式化操作
now := time.Now()
// 格式化的模板為 2006-01-02 15:04:05
// 24小時制
fmt.Println(now.Format("2006-01-02 15:04:05.000 Mon Jan"))
// 12小時制
fmt.Println(now.Format("2006-01-02 03:04:05.000 PM Mon Jan"))
// 小數點後寫0,因為有3個0所以格式化輸出的結果也保留3位小數
fmt.Println(now.Format("2006/01/02 15:04:05.000"))
// 小數點後寫9,會省略末尾可能出現的0
fmt.Println(now.Format("2006/01/02 15:04:05.999"))
// 只格式化時分秒部分
fmt.Println(now.Format("15:04:05"))
// 只格式化日期部分
fmt.Println(now.Format("2006.01.02"))
}
七.解析字串的時間
1.解析時間的函式
對於從文字的時間表示中解析出時間物件,time包中提供了time.Parse和time.ParseInLocation兩個函式。
其中time.Parse在解析時不需要額外指定時區資訊。
time.ParseInLocation函式需要在解析時額外指定時區資訊。
2.Parse從文字解析時間
package main
import (
"fmt"
"time"
)
func main() {
// 在沒有時區指示符的情況下,time.Parse 返回UTC時間
t1, _ := time.Parse("2006/01/02 15:04:05", "2030/10/05 11:25:20")
// 在有時區指示符的情況下,time.Parse 返回對應時區的時間表示
// RFC3339 = "2006-01-02T15:04:05Z07:00"
t2, _ := time.Parse(time.RFC3339, "2030-10-05T11:25:20+08:00")
fmt.Printf("t1 = [%v], t2 = [%v]\n", t1, t2)
}
3.ParseInLocation從文字解析時間
package main
import (
"fmt"
"time"
)
func main() {
now := time.Now()
// 載入時區
timezone, _ := time.LoadLocation("Asia/Shanghai")
// 按照指定時區和指定格式解析字串時間
t1, _ := time.ParseInLocation("2006/01/02 15:04:05", "2030/07/20 11:25:20", timezone)
fmt.Println(now)
fmt.Println(t1.Sub(now))
}
八.練習題
1.獲取當前時間,格式化輸出為"2030/01/01 23:30:05"格式
package main
import (
"fmt"
"time"
)
func PrintTime(t time.Time) {
// 方式一: Go語言中時間格式化的佈局不是常見的Y-m-d H:M:S,而是使用 2006-01-02 15:04:05.000(記憶口訣為2006 1 2 3 4 5)
// 溫馨提示:
// 1."2006/01/02 15:04:05"分別對應著年月日時分秒;
// 2.如果只想看年則傳入"2006",如果想要看月份則傳入"01",如果想要看小時則傳入15,以此推類;
t1 := t.Format("2006/01/02 15:04:05")
fmt.Printf("t1 = [%v]\n", t1)
// 方式二: 使用Sprintf
t2 := fmt.Sprintf("%d/%d/%d %d:%d:%d", t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute(), t.Second())
fmt.Printf("t2 = [%v]\n", t2)
}
func main() {
now := time.Now()
PrintTime(now)
}
2.編寫程式統計一段程式碼的執行耗時時間,單位精確到微秒。
package main
import (
"fmt"
"time"
)
func calctime1() {
// 計算出納秒
start := time.Now().UnixNano() / 1000
fmt.Println("正在執行程式碼...")
time.Sleep(time.Millisecond * 50)
end := time.Now().UnixNano() / 1000
fmt.Printf("in calctime1()... 耗費了%v微妙\n", end-start)
}
func calctime2() {
start := time.Now()
fmt.Println("正在執行程式碼...")
time.Sleep(time.Millisecond * 100)
// 注意, time.Since時內建的方法,就是拿當前的時間減去start的時間喲。
fmt.Printf("in calctime2()... 耗費了%v\n", time.Since(start))
}
func main() {
calctime1()
calctime2()
}