時(shí)間和日期是我們編程中經(jīng)常會(huì)用到的泉哈,本文主要介紹了Go語(yǔ)言內(nèi)置的time包的基本用法帚桩。
time包
time包提供了時(shí)間的顯示和測(cè)量用的函數(shù)瑟匆。日歷的計(jì)算采用的是公歷处渣。
時(shí)間類型
time.Time
類型表示時(shí)間。我們可以通過(guò)time.Now()
函數(shù)獲取當(dāng)前的時(shí)間對(duì)象诱贿,然后獲取時(shí)間對(duì)象的年月日時(shí)分秒等信息娃肿。示例代碼如下:
func timeDemo() {
now := time.Now() //獲取當(dāng)前時(shí)間
fmt.Printf("current time:%v\n", now)
year := now.Year() //年
month := now.Month() //月
day := now.Day() //日
hour := now.Hour() //小時(shí)
minute := now.Minute() //分鐘
second := now.Second() //秒
fmt.Printf("%d-%02d-%02d %02d:%02d:%02d\n", year, month, day, hour, minute, second)
}
時(shí)間戳
時(shí)間戳是自1970年1月1日(08:00:00GMT)至當(dāng)前時(shí)間的總毫秒數(shù)咕缎。它也被稱為Unix時(shí)間戳(UnixTimestamp)。
基于時(shí)間對(duì)象獲取時(shí)間戳的示例代碼如下:
func timestampDemo() {
now := time.Now() //獲取當(dāng)前時(shí)間
timestamp1 := now.Unix() //時(shí)間戳
timestamp2 := now.UnixNano() //納秒時(shí)間戳
fmt.Printf("current timestamp1:%v\n", timestamp1)
fmt.Printf("current timestamp2:%v\n", timestamp2)
}
使用time.Unix()
函數(shù)可以將時(shí)間戳轉(zhuǎn)為時(shí)間格式料扰。
func timestampDemo2(timestamp int64) {
timeObj := time.Unix(timestamp, 0) //將時(shí)間戳轉(zhuǎn)為時(shí)間格式
fmt.Println(timeObj)
year := timeObj.Year() //年
month := timeObj.Month() //月
day := timeObj.Day() //日
hour := timeObj.Hour() //小時(shí)
minute := timeObj.Minute() //分鐘
second := timeObj.Second() //秒
fmt.Printf("%d-%02d-%02d %02d:%02d:%02d\n", year, month, day, hour, minute, second)
}
時(shí)間間隔
time.Duration
是time
包定義的一個(gè)類型凭豪,它代表兩個(gè)時(shí)間點(diǎn)之間經(jīng)過(guò)的時(shí)間,以納秒為單位晒杈。time.Duration
表示一段時(shí)間間隔嫂伞,可表示的最長(zhǎng)時(shí)間段大約290年。
time包中定義的時(shí)間間隔類型的常量如下:
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秒帖努。
時(shí)間操作
Add
我們?cè)谌粘5木幋a過(guò)程中可能會(huì)遇到要求時(shí)間+時(shí)間間隔的需求,Go語(yǔ)言的時(shí)間對(duì)象有提供Add方法如下:
func (t Time) Add(d Duration) Time
舉個(gè)例子粪般,求一個(gè)小時(shí)之后的時(shí)間:
func main() {
now := time.Now()
later := now.Add(time.Hour) // 當(dāng)前時(shí)間加1小時(shí)后的時(shí)間
fmt.Println(later)
}
Sub
求兩個(gè)時(shí)間之間的差值:
func (t Time) Sub(u Time) Duration
返回一個(gè)時(shí)間段t-u拼余。如果結(jié)果超出了Duration可以表示的最大值/最小值,將返回最大值/最小值亩歹。要獲取時(shí)間點(diǎn)t-d(d為Duration)匙监,可以使用t.Add(-d)。
now := time.Now() //本地的時(shí)間
fmt.Println(now)
//明天的這個(gè)時(shí)間
//按照指定格式取解析一個(gè)字符串格式的時(shí)間
time.Parse("2009-01-02 15:04:05","2022-01-10 14:41:50" )
//按照東八區(qū)的時(shí)區(qū)和格式取解析一個(gè)字符串格式的時(shí)間
//根據(jù)字符串加載時(shí)區(qū)
loc, err := time.LoadLocation("Asia/Shanghai")
if err != nil {
fmt.Printf("load loc failed, err:%v\n", err)
return
}
//按照指定時(shí)區(qū)解析時(shí)間
time0bj, err := time.ParseInLocation("2009-01-02 15:04:05","2022-01-10 14:41:50", loc)
if err != nil {
fmt.Printf("parse time failed, err:%v\n", err)
return
}
fmt.Println(timeObj)
//時(shí)間對(duì)象相減
td := timeObj.Sub(now)
fmt.Println(td)
Equal
func (t Time) Equal(u Time) bool
判斷兩個(gè)時(shí)間是否相同捆憎,會(huì)考慮時(shí)區(qū)的影響舅柜,因此不同時(shí)區(qū)標(biāo)準(zhǔn)的時(shí)間也可以正確比較。本方法和用t==u不同躲惰,這種方法還會(huì)比較地點(diǎn)和時(shí)區(qū)信息。
Before
func (t Time) Before(u Time) bool
如果t代表的時(shí)間點(diǎn)在u之前变抽,返回真础拨;否則返回假。
After
func (t Time) After(u Time) bool
如果t代表的時(shí)間點(diǎn)在u之后绍载,返回真诡宗;否則返回假。
Sleep
func Sleep(d Duration)
傳入的為一個(gè)Duration击儡,所以如果想睡眠5s鐘塔沃,不能直接寫 time.Sleep(5) ,而應(yīng)該寫time.Sleep(5 * time.Second)
其中time.Second就是一個(gè)Duration類型阳谍,表示1s的時(shí)間間隔蛀柴,乘系數(shù)5就得到5s的時(shí)間間隔。
n := 5 //int
time.Sleep(time.Duration(n) * time.Second)
go提供了不同的時(shí)間單位:
const (
Nanosecond Duration = 1
Microsecond = 1000 * Nanosecond
Millisecond = 1000 * Microsecond
Second = 1000 * Millisecond
Minute = 60 * Second
Hour = 60 * Minute
)
Nanosecond表示1納秒的時(shí)間間隔
Microsecond表示1微妙的時(shí)間間隔
Millisecond表示1毫秒的時(shí)間間隔
Second表示1秒的時(shí)間間隔
Minute表示1分鐘的時(shí)間間隔
Hour表示1小時(shí)的時(shí)間間隔
想要睡眠的時(shí)間可以使用以上的常量自由組合
比如睡眠1小時(shí)10分5秒:
time.Sleep(1*time.Hour + 10*time.Minute + 5*time.Second)
定時(shí)器
使用time.Tick(時(shí)間間隔)
來(lái)設(shè)置定時(shí)器矫夯,定時(shí)器的本質(zhì)上是一個(gè)通道(channel)鸽疾。
func tickDemo() {
ticker := time.Tick(time.Second) //定義一個(gè)1秒間隔的定時(shí)器
for i := range ticker {
fmt.Println(i)//每秒都會(huì)執(zhí)行的任務(wù)
}
}
時(shí)間格式化
時(shí)間類型有一個(gè)自帶的方法Format
進(jìn)行格式化,需要注意的是Go語(yǔ)言中格式化時(shí)間模板不是常見(jiàn)的Y-m-d H:M:S
而是使用Go的誕生時(shí)間2006年1月2號(hào)15點(diǎn)04分(記憶口訣為2006 1 2 3 4)训貌。也許這就是技術(shù)人員的浪漫吧制肮。
補(bǔ)充:如果想格式化為12小時(shí)方式冒窍,需指定PM
。
func formatDemo() {
now := time.Now()
// 格式化的模板為Go的出生時(shí)間2006年1月2號(hào)15點(diǎn)04分 Mon Jan
// 24小時(shí)制
fmt.Println(now.Format("2006-01-02 15:04:05.000 Mon Jan"))
// 12小時(shí)制
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"))
}
解析字符串格式的時(shí)間
now := time.Now()
fmt.Println(now)
// 加載時(shí)區(qū)
loc, err := time.LoadLocation("Asia/Shanghai")
if err != nil {
fmt.Println(err)
return
}
// 按照指定時(shí)區(qū)和指定格式解析字符串時(shí)間
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)
fmt.Println(timeObj.Sub(now))