Go語言的time庫中包含了對時間進行管理的所有操作,本文介紹一下time庫的使用,後續持續更新。
1. 時間的類型
Go語言的time庫採用公曆的方式記錄日期,我們可以通過time.Now()函數獲取當前的時間對象,然後獲取時間對象的年月日時分秒等信息。
func main() {
now := time.Now()
fmt.Printf("當前時間是:%s\n", now.String())
fmt.Printf("%d年", now.Year())
fmt.Printf("%d月", now.Month())
fmt.Printf("%d日", now.Day())
fmt.Printf("\t%d:", now.Hour())
fmt.Printf("%d:", now.Minute())
fmt.Printf("%d", now.Second())
}
Output:
$ go run main.go
當前時間是:2020-05-23 23:12:30.6339153 +0800 CST m=+0.013003701
2020年5月23日 23:12:30
2.時間戳
時間戳是自1970年1月1日(08:00:00GMT)至當前時間的總毫秒數。它也被稱爲Unix時間戳(UnixTimestamp),我們可以將時間戳轉化爲我們想要的時間格式。
func main() {
now := time.Now() //獲取當前時間
timestamp1 := now.Unix() //時間戳
timestamp2 := now.UnixNano() //納秒時間戳
fmt.Printf("current timestamp1:%v\n", timestamp1)
fmt.Printf("current timestamp2:%v\n", timestamp2)
// 時間戳格式化
// time.Unix有兩個參數,第一個時秒時間戳,另一個是納秒時間戳
now2 := time.Unix(timestamp1, 0)
fmt.Printf("當前時間是:%s\n", now2.String())
fmt.Printf("%d年", now.Year())
fmt.Printf("%d月", now.Month())
fmt.Printf("%d日", now.Day())
fmt.Printf("\t%d:", now.Hour())
fmt.Printf("%d:", now.Minute())
fmt.Printf("%d", now.Second())
}
Output:
$ go run main.go
current timestamp1:1590247321
current timestamp2:1590247321140010600
當前時間是:2020-05-23 23:22:01 +0800 CST
2020年5月23日 23:22:1
3.時間間隔
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
)
時間間隔在我們實際開發中使用還是比較多的,比如記錄一個程序運行了多長時間,在下面寫一個demo,爲了模擬時間差,裏面用到了下面會將的時間操作函數:
func main() {
now := time.Now() //獲取當前時間
// 時間間隔4000秒
endTime := now.Add(time.Second * 4000)
// 計算時間間隔
Duration := time.Unix(0, endTime.Sub(now).Nanoseconds())
// 時間戳是自1970年1月1日(08:00:00GMT)至當前時間的總毫秒數,因此給小時減去8就是準確的時間差了
fmt.Printf("用時: %d小時%d分鐘%d秒", Duration.Hour()-8, Duration.Minute(), Duration.Second())
}
Output:
$ go run main.go
用時: 1小時6分鐘40秒
4.時間操作
【1】增加時間,這個在上面的例子已經使用了,使用Add方法就可以對時間進行增加的操作。
func main() {
now := time.Now() //獲取當前時間
fmt.Printf("當前時間是: %s\n", now.String())
// 時間間隔4000秒, 注意這裏時間間隔可以爲負數,負數表示時間相減
BeforeTime := now.Add(-time.Second * 4000)
fmt.Printf("4000秒前的時間是: %s", BeforeTime.String())
}
Output:
$ go run main.go
當前時間是: 2020-05-23 23:52:31.1246786 +0800 CST m=+0.008997901
4000秒前的時間是: 2020-05-23 22:45:51.1246786 +0800 CST m=-3999.991002099
【2】求事件差,這個在上面的例子中也用到了,使用Sub方法就可以對兩個時間進行求差了。
func main() {
now := time.Now() //獲取當前時間
fmt.Printf("當前時間是: %s\n", now.String())
// 時間間隔4000秒
endTime := now.Add(time.Second * 4000)
// 計算時間間隔,endTime-now
Duration := time.Unix(0, endTime.Sub(now).Nanoseconds())
// 時間戳是自1970年1月1日(08:00:00GMT)至當前時間的總毫秒數,因此給小時減去8就是準確的時間差了
fmt.Printf("用時: %d小時%d分鐘%d秒", Duration.Hour()-8, Duration.Minute(), Duration.Second())
}
【3】比較兩個時間是否相同。
func main() {
//獲取當前時間
now := time.Now()
// 時間間隔4000秒
EndTime := now.Add(time.Second * 4000)
fmt.Printf("當前時間是: %s\n", now.String())
fmt.Printf("EndTime 是: %s\n", EndTime.String())
if now.Equal(EndTime) {
fmt.Println("兩個時間相同")
} else {
fmt.Println("兩段時間不相同")
}
}
Output:
$ go run main.go
當前時間是: 2020-05-24 09:36:26.9891533 +0800 CST m=+0.010997301
EndTime 是: 2020-05-24 10:43:06.9891533 +0800 CST m=+4000.010997301
兩段時間不相同
【4】比較兩個時間是否前者早於後者。
func main() {
//獲取當前時間
now := time.Now()
// 時間間隔4000秒
EndTime := now.Add(time.Second * 4000)
fmt.Printf("當前時間是: %s\n", now.String())
fmt.Printf("EndTime 是: %s\n", EndTime.String())
if now.Before(EndTime) {
fmt.Println("當前時間小於EndTime")
} else {
fmt.Println("當前時間大於EndTime")
}
}
Output:
$ go run main.go
當前時間是: 2020-05-24 09:39:59.9618812 +0800 CST m=+0.010003801
EndTime 是: 2020-05-24 10:46:39.9618812 +0800 CST m=+4000.010003801
當前時間小於EndTime
【5】比較兩個時間是否前者晚於後者。
func main() {
//獲取當前時間
now := time.Now()
// 時間間隔4000秒
EndTime := now.Add(time.Second * 4000)
fmt.Printf("當前時間是: %s\n", now.String())
fmt.Printf("EndTime 是: %s\n", EndTime.String())
if now.After(EndTime) {
fmt.Println("當前時間在EndTime之後")
} else {
fmt.Println("當前時間在EndTime之前")
}
}
Output:
$ go run main.go
當前時間是: 2020-05-24 09:41:40.713311 +0800 CST m=+0.011991301
EndTime 是: 2020-05-24 10:48:20.713311 +0800 CST m=+4000.011991301
當前時間在EndTime之前
5.定時器
使用time.Tick(時間間隔)來設置定時器,定時器的本質上是一個通道(channel)。
func main() {
tick := time.Tick(time.Second)
for v := range tick {
//獲取當前時間
fmt.Println("Now: ", time.Now().Second(), "tick: ", v)
}
}
Output:
$ go run main.go
Now: 5 tick: 2020-05-24 09:46:05.7408253 +0800 CST m=+1.015033901
Now: 6 tick: 2020-05-24 09:46:06.7420162 +0800 CST m=+2.016224801
Now: 7 tick: 2020-05-24 09:46:07.7408322 +0800 CST m=+3.015040801
Now: 8 tick: 2020-05-24 09:46:08.7408017 +0800 CST m=+4.015010301
可以看到這個循環每秒執行一次。
6.時間的格式化
時間類型有一個自帶的方法Format進行格式化,需要注意的是Go語言中格式化時間模板不是常見的Y-m-d H:M:S而是使用Go的誕生時間2006年1月2號15點04分(記憶口訣爲2006 1 2 3 4)。也許這就是技術人員的浪漫吧。
補充:如果想格式化爲12小時方式,需指定PM。
func main() {
now := time.Now()
// 格式化的模板爲Go的出生時間2006年1月2號15點04分 Mon Jan
// 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"))
fmt.Println(now.Format("2006/01/02 15:04"))
fmt.Println(now.Format("15:04 2006/01/02"))
fmt.Println(now.Format("2006/01/02"))
}
Output:
$ go run main.go
2020-05-24 09:50:08.741 Sun May
2020-05-24 09:50:08.741 AM Sun May
2020/05/24 09:50
09:50 2020/05/24
2020/05/24
當然你也可以將字符串解析爲你想要的時間格式:
func main() {
now := time.Now()
fmt.Println(now)
// 加載時區
loc, err := time.LoadLocation("Asia/Shanghai")
if err != nil {
fmt.Println(err)
return
}
// 按照指定時區和指定格式解析字符串時間
timeObj, err := time.ParseInLocation("2006/01/02 15:04:05", "2019/08/04 14:15:20", loc)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(timeObj)
}
Output:
$ go run main.go
2020-05-24 09:52:52.7381466 +0800 CST m=+0.009007901
2019-08-04 14:15:20 +0800 CST
7.時間格式
【1】UTC
Universal Time Coordinated 協調世界時,又稱世界標準時間。多數的兩地時間表都以GMT來表示,但也有些兩地時間表上看不到GMT字樣,出現的反而是UTC這3個英文字母,究竟何謂UTC?事實上,UTC指的是Coordinated Universal Time- 世界協調時間(又稱世界標準時間、世界統一時間),是經過平均太陽時(以格林威治時間GMT爲準)、地軸運動修正後的新時標以及以「秒」爲單位的國際原子時所綜合精算而成的時間,計算過程相當嚴謹精密,因此若以「世界標準時間」的角度來說,UTC比GMT來得更加精準。其誤差值必須保持在0.9秒以內,若大於0.9秒則由位於巴黎的國際地球自轉事務中央局發佈閏秒,使UTC與地球自轉週期一致。所以基本上UTC的本質強調的是比GMT更爲精確的世界時間標準,不過對於現行錶款來說,GMT與UTC的功能與精確度是沒有差別的。
【2】GMT
Greenwich Mean Time 格林尼治平均時
UTC和GMT都與英國倫敦的本地時相同,所以程序中UTC與GMT沒什麼不同。意思UTC=GMT是相等的
十七世紀,格林威治皇家天文臺爲了海上霸權的擴張計畫而進行天體觀測。1675年舊皇家觀測所(Old Royal Observatory) 正式成立,到了1884年決定以通過格林威治的子午線作爲劃分地球東西兩半球的經度零度。觀測所門口牆上有一個標誌24小時的時鐘,顯示當下的時間,對全球而言,這裏所設定的時間是世界時間參考點,全球都以格林威治的時間作爲標準來設定時間,這就是我們耳熟能詳的「格林威治標準時間」(Greenwich Mean Time,簡稱G.M.T.)的由來,標示在手錶上,則代表此表具有兩地時間功能,也就是同時可以顯示原居地和另一個國度的時間。
【3】Unix時間戳
在計算機中看到的UTC時間都是從(1970年01月01日 0:00:00)開始計算秒數的。所看到的UTC時間那就是從1970年這個時間點起到具體時間共有多少秒。 這個秒數就是Unix時間戳。
【4】CST時間
CST卻同時可以代表如下 4 個不同的時區:
Central Standard Time (USA) UT-6:00
Central Standard Time (Australia) UT+9:30
China Standard Time UT+8:00
Cuba Standard Time UT-4:00
【5】CET
(英語:Central European Time,CET)歐洲中部時間是比世界標準時間(UTC)早一個小時的時區名稱之一。它被大部分歐洲國家和部分北非國家採用。冬季時間爲UTC+1,夏季歐洲夏令時爲UTC+2。
【6】DST
Daylight Saving Time「夏日節約時間」
是指在夏天太陽升起的比較早時,將時鐘撥快一小時,以提早日光的使用,在英國則稱爲夏令時間(Summer Time)。這個構想於1784年由美國班傑明·富蘭克林提出來,1915年德國成爲第一個正式實施夏令日光節約時間的國家,以削減燈光照明和耗電開支。自此以後,全球以歐洲和北美爲主的約70個國家都引用這個做法。目前被劃分成兩個時區的印度也正在商討是否全國該統一實行夏令日光節約時間。歐洲手機上也有很多GSM系統的基地臺,除了會傳送當地時間外也包括夏令日光節約時間,做爲手機的時間標準,使用者可以自行決定要開啓或關閉。值得注意的是,某些國家有實施「夏日節約時間」的制度,出國時別忘了跟隨當地習慣在表上調整一下,這可是機械錶沒有的功能設計哦!
【7】不同時間的關係
- UTC=GMT
- CET=UTC/GMT + 1小時
- CST=UTC/GMT +8 小時
- CST=CET+9