Golang 時間操作大全
平時開發(fā)過程中,時間相關(guān)的操作用的還是很多的。接下來就與大家一起總結(jié)下與時間有關(guān)的操作,主要涉及到 time 包,核心數(shù)據(jù)結(jié)構(gòu)是 time.Time,如下:
type?Time?struct?{
????wall?uint64
????ext??int64
????loc?*Location
}
00 獲取時間相關(guān)函數(shù)
0.獲取當(dāng)前時間
//?返回當(dāng)前時間,注意此時返回的是?time.Time?類型
now?:=?time.Now()
fmt.Println(now)
//?當(dāng)前時間戳
fmt.Println(now.Unix())
//?納秒級時間戳
fmt.Println(now.UnixNano())
//?時間戳小數(shù)部分?單位:納秒
fmt.Println(now.Nanosecond())
輸出:
2021-01-10?14:56:15.930562?+0800?CST?m=+0.000124449
1610261775
1610261775930562000
930562000
1.返回當(dāng)前年月日時分秒、星期幾、一年中的第幾天等操作
now?:=?time.Now()
//?返回日期
year,?month,?day?:=?now.Date()
fmt.Printf("year:%d,?month:%d,?day:%d\n",?year,?month,?day)
//?年
fmt.Println(now.Year())
//?月
fmt.Println(now.Month())
//?日
fmt.Println(now.Day())
//?時分秒
hour,?minute,?second?:=?now.Clock()
fmt.Printf("hour:%d,?minute:%d,?second:%d\n",?hour,?minute,?second)
//?時
fmt.Println(now.Hour())
//?分
fmt.Println(now.Minute())
//?秒
fmt.Println(now.Second())
//?返回星期
fmt.Println(now.Weekday())
//返回一年中對應(yīng)的第幾天
fmt.Println(now.YearDay())
//返回時區(qū)
fmt.Println(now.Location())
//?返回一年中第幾天
fmt.Println(now.YearDay())
2.格式化時間
Go 語言提供了時間類型格式化函數(shù) Format(),需要注意的是 Go 語言格式化時間模板不是常見的 Y-m-d H:i:s,而是 2006-01-02 15:04:05,也很好記憶(2006 1 2 3 4 5)。
now?:=?time.Now()
fmt.Println(now.Format("2006-01-02?15:03:04"))
fmt.Println(now.Format("2006-01-02"))
fmt.Println(now.Format("15:03:04"))
fmt.Println(now.Format("2006/01/02?15:04"))
fmt.Println(now.Format("15:04?2006/01/02"))
01 時間戳與日期字符串相互轉(zhuǎn)化
時間戳怎么轉(zhuǎn)成日期格式呢?由 0.2 節(jié)可以知道,需要先轉(zhuǎn)成將時間戳轉(zhuǎn)成 time.Time 類型再格式化成日期格式。
0.根據(jù)秒數(shù)、納秒數(shù)返回 time.Time 類型
now?:=?time.Now()
layout?:=?"2006-01-02?15:04:05"
t?:=?time.Unix(now.Unix(),0)????//?參數(shù)分別是:秒數(shù),納秒數(shù)
fmt.Println(t.Format(layout))
1.根據(jù)指定時間返回 time.Time 類型,使用函數(shù) time.Date()
now?:=?time.Now()
layout?:=?"2006-01-02?15:04:05"
//根據(jù)指定時間返回?time.Time?類型
//分別指定年,月,日,時,分,秒,納秒,時區(qū)
t?:=?time.Date(2011,?time.Month(3),?12,?15,?30,?20,?0,?now.Location())
fmt.Println(t.Format(layout))
2.日期字符串解析成 time.Time 類型
t,?_?:=?time.ParseInLocation("2006-01-02?15:04:05",?time.Now().Format("2006-01-02?15:04:05"),?time.Local)
fmt.Println(t)??
//?輸出?2021-01-10?17:28:50?+0800?CST
//?time.Local?指定本地時間
解析的時候需要特別注意時區(qū)的問題:
fmt.Println(time.Now())
fmt.Println(time.Now().Location())
t,?_?:=?time.Parse("2006-01-02?15:04:05",?"2021-01-10?15:01:02")
fmt.Println(t)
輸出:
2021-01-10?17:22:10.951904?+0800?CST?m=+0.000094166
Local
2021-01-10?15:01:02?+0000?UTC
可以看到,time.Now() 使用的 CST(中國標(biāo)準(zhǔn)時間),而 time.Parse() 默認(rèn)的是 UTC(零時區(qū)),它們相差 8 小時。所以解析時常用 time.ParseInLocation(),可以指定時區(qū)。
重點!!!
畫了張圖,幫助大家理清時間戳、time.Time 和 日期格式?之間的轉(zhuǎn)化關(guān)系:

03 計算、比較日期
講到日期的計算就不得不提 time 包提供的一種新的類型 Duration,源碼是這樣定義的:
type?Duration?int64
底層類型是 int64,表示一段時間間隔,單位是 納秒。
0.24小時之內(nèi)的時間計算
now?:=?time.Now()
fmt.Println(now)
//?1小時1分1s之后
t1,?_?:=?time.ParseDuration("1h1m1s")
fmt.Println(t1)
m1?:=?now.Add(t1)
fmt.Println(m1)
//?1小時1分1s之前
t2,?_?:=?time.ParseDuration("-1h1m1s")
m2?:=?now.Add(t2)
fmt.Println(m2)
//?3小時之前
t3,?_?:=?time.ParseDuration("-1h")
m3?:=?now.Add(t3?*?3)
fmt.Println(m3)
//?10?分鐘之后
t4,?_?:=?time.ParseDuration("10m")
m4?:=?now.Add(t4)
fmt.Println(m4)
//?Sub?計算兩個時間差
sub1?:=?now.Sub(m3)
fmt.Println(sub1.Hours())???//?相差小時數(shù)
fmt.Println(sub1.Minutes())?//?相差分鐘數(shù)
額外再介紹兩個函數(shù) time.Since()、time.Until():
//?返回當(dāng)前時間與?t?的時間差,返回值是?Duration
time.Since(t?Time)?Duration
//?返回?t?與當(dāng)前時間的時間差,返回值是?Duration
time.Until(t?Time)?Duration
now?:=?time.Now()
fmt.Println(now)
t1,?_?:=?time.ParseDuration("-1h")
m1?:=?now.Add(t1)
fmt.Println(m1)
fmt.Println(time.Since(m1))
fmt.Println(time.Until(m1))
輸出:
2021-01-10?20:41:48.668232?+0800?CST?m=+0.000095594
2021-01-10?19:41:48.668232?+0800?CST?m=-3599.999904406
1h0m0.000199007s
-1h0m0.000203035s
1.24小時之外的時間計算
涉及到一天以外的時間計算,就需要用到 time.AddDate(),函數(shù)原型:
func?(t?Time)?AddDate(years?int,?months?int,?days?int)?Time
比如我們想知道 一年一個月零一天 之后的時間,就可以這樣:
now?:=?time.Now()
fmt.Println(now)
m1?:=?now.AddDate(1,1,1)
fmt.Println(m1)
再比如,我們想獲得 2 天之前時間:
now?:=?time.Now()
fmt.Println(now)
m1?:=?now.AddDate(0,0,-2)
fmt.Println(m1)
2.日期比較
日期的比較總共有三種:之前、之后和相等。
//?如果 t 代表的時間點在 u 之前,返回真;否則返回假。
func?(t?Time)?Before(u?Time)?bool
//?如果?t?代表的時間點在?u?之后,返回真;否則返回假。
func?(t?Time)?After(u?Time)?bool
//?比較時間是否相等,相等返回真;否則返回假。
func?(t?Time)?Equal(u?Time)?bool
now?:=?time.Now()
fmt.Println(now)
//?1小時之后
t1,?_?:=?time.ParseDuration("1h")
m1?:=?now.Add(t1)
fmt.Println(m1)
fmt.Println(m1.After(now))
fmt.Println(now.Before(m1))
fmt.Println(now.Equal(m1))
輸出:
2021-01-10?21:00:44.409785?+0800?CST?m=+0.000186800
2021-01-10?22:00:44.409785?+0800?CST?m=+3600.000186800
true
true
false
04 常見例子
下面列舉一些常見的例子和函數(shù)封裝。
0.日期格式 轉(zhuǎn) 時間戳
func?TimeStr2Time(fmtStr,valueStr,?locStr?string)?int64?{
????loc?:=?time.Local
????if?locStr?!=?""?{
????????loc,?_?=?time.LoadLocation(locStr)?//?設(shè)置時區(qū)
????}
????if?fmtStr?==?""?{
????????fmtStr?=?"2006-01-02?15:04:05"
????}
????t,?_?:=?time.ParseInLocation(fmtStr,?valueStr,?loc)
????return?t.Unix()
}
1.獲取當(dāng)前時間日期格式
func?GetCurrentFormatStr(fmtStr?string)?string?{
????if?fmtStr?==?""?{
????????fmtStr?=?"2006-01-02?15:04:05"
????}
????return?time.Now().Format(fmtStr)
}
2.時間戳 to 日期格式
func?Sec2TimeStr(sec?int64,?fmtStr?string)?string?{
????if?fmtStr?==?""?{
????????fmtStr?=?"2006-01-02?15:04:05"
????}
????return?time.Unix(sec,?0).Format(fmtStr)
}
推薦閱讀
給個[在看],是對四哥最大的支持

