Go 学习笔记(48)— Go 标准库之 time (获取时/分/秒的单位值、标准时间和Unix时间转换、字符串时间和Time类型转换、时区转换、时间的加减/休眠)
1. 概要說(shuō)明
import "time"
time 包提供了時(shí)間的顯示和測(cè)量用的函數(shù)。日歷的計(jì)算采用的是公歷。
Go 提供以下幾種時(shí)間類型:
- 時(shí)間點(diǎn)
Time - 時(shí)間段
Duration - 時(shí)區(qū)
Location Ticker- 定時(shí)器
Timer
2. Time 類型
type Time struct {// 內(nèi)含隱藏或非導(dǎo)出字段
}
Time 代表一個(gè)納秒精度的時(shí)間點(diǎn)。
程序中應(yīng)使用 Time 類型值來(lái)保存和傳遞時(shí)間,而不能用指針。就是說(shuō),表示時(shí)間的變量和字段,應(yīng)為 time.Time 類型,而不是 *time.Time 類型。
時(shí)間點(diǎn)可以使用 Before 、 After 和 Equal 方法進(jìn)行比較。
Sub方法讓兩個(gè)時(shí)間點(diǎn)相減,生成一個(gè)Duration類型值(代表時(shí)間段);Add方法給一個(gè)時(shí)間點(diǎn)加上一個(gè)時(shí)間段,生成一個(gè)新的Time類型時(shí)間點(diǎn);
Time 零值代表時(shí)間點(diǎn) January 1, year 1, 00:00:00.000000000 UTC。因?yàn)楸緯r(shí)間點(diǎn)一般不會(huì)出現(xiàn)在使用中, IsZero 方法提供了檢驗(yàn)時(shí)間是否顯式初始化的一個(gè)簡(jiǎn)單途徑。
每一個(gè)時(shí)間都具有一個(gè)地點(diǎn)信息(及對(duì)應(yīng)地點(diǎn)的時(shí)區(qū)信息),當(dāng)計(jì)算時(shí)間的表示格式時(shí),如 Format 、 Hour 和 Year 等方法,都會(huì)考慮該信息。 Local 、 UTC 和 In 方法返回一個(gè)指定時(shí)區(qū)(但指向同一時(shí)間點(diǎn))的 Time 。修改地點(diǎn)/時(shí)區(qū)信息只是會(huì)改變其表示;不會(huì)修改被表示的時(shí)間點(diǎn),因此也不會(huì)影響其計(jì)算。
2.1 Time 類型函數(shù)
2.1.1 func Date
func Date(year int, month Month, day, hour, min, sec, nsec int, loc *Location) Time
Date 返回一個(gè)時(shí)區(qū)為 loc 、當(dāng)?shù)貢r(shí)間為:
year-month-day hour:min:sec + nsec nanoseconds 的時(shí)間點(diǎn)。
代碼示例:
func main() {timeDate := time.Date(2020, 05, 23, 10, 11, 12, 13, time.Local)fmt.Printf("timeDate is %v, type is %T", timeDate, timeDate)// timeDate is 2020-05-23 10:11:12.000000013 +0800 CST, type is time.Time
}
2.1.2 func Now
func Now() Time
Now 返回當(dāng)前本地時(shí)間。
代碼示例:
func main() {timeNow := time.Now()fmt.Printf("timeNow is %v, type is %T", timeNow, timeNow)// timeNow is 2020-05-23 10:23:11.061117 +0800 CST m=+0.005000301, type is time.Time
}
2.1.3 func Parse
func Parse(layout, value string) (Time, error)
Parse 解析一個(gè)格式化的時(shí)間字符串并返回它代表的時(shí)間。 layout 定義了參考時(shí)間:
Mon Jan 2 15:04:05 -0700 MST 2006,注意 layout 必須為 “2006-01-02 15:04:05”,否則會(huì)報(bào)錯(cuò)誤:
parsing time "2020-05-22 10:25:30": month out of range
代碼示例:
func main() {timeParse, err := time.Parse("2006-01-02 15:04:05", "2020-05-22 10:25:30")if err != nil {fmt.Println("time parse failed: ", err)}fmt.Printf("timeParse is %v, type is %T", timeParse, timeParse)// timeParse is 2020-05-22 10:25:30 +0000 UTC, type is time.Time
}
2.1.4 func ParseInLocation
func ParseInLocation(layout, value string, loc *Location) (Time, error)
ParseInLocation 類似 Parse 但有兩個(gè)重要的不同之處:
- 當(dāng)缺少時(shí)區(qū)信息時(shí),
Parse將時(shí)間解釋為UTC時(shí)間,而ParseInLocation將返回值的Location設(shè)置為loc; - 當(dāng)時(shí)間字符串提供了時(shí)區(qū)偏移量信息時(shí),
Parse會(huì)嘗試去匹配本地時(shí)區(qū),而ParseInLocation會(huì)去匹配loc
代碼示例:
func main() {ParseInLocation, err := time.ParseInLocation("2006-01-02 15:04:05", "2020-05-22 10:25:30", time.Local)if err != nil {fmt.Println("time ParseInLocation failed: ", err)}fmt.Printf("ParseInLocation is %v, type is %T", ParseInLocation, ParseInLocation)// ParseInLocation is 2020-05-22 10:25:30 +0800 CST, type is time.Time
}
2.1.5 func Unix
func Unix(sec int64, nsec int64) Time
Unix 創(chuàng)建一個(gè)本地時(shí)間,對(duì)應(yīng) sec 和 nsec 表示的 Unix 時(shí)間(從January 1, 1970 UTC至該時(shí)間的秒數(shù)和納秒數(shù))。
nsec 的值在 [0, 999999999] 范圍外是合法的。
代碼示例:
func main() {timeUnix := time.Unix(322020993, 3939993399848320)fmt.Printf("timeUnix is %v, type is %T", timeUnix, timeUnix)// timeUnix is 1980-05-01 00:43:06.39984832 +0800 CST, type is time.Time
}
以上的函數(shù) Date 、 Now 、 Parse 、 ParseInLocation 、 Unix 返回的都是 Time 類型的結(jié)構(gòu)體。
2.2 Time 類型方法
Time 類型有很多結(jié)構(gòu)體方法,如下表所示:
func (t Time) Location() *Location
func (t Time) Zone() (name string, offset int)
func (t Time) IsZero() bool
func (t Time) Local() Time
func (t Time) UTC() Time
func (t Time) In(loc *Location) Time
func (t Time) Unix() int64
func (t Time) UnixNano() int64
func (t Time) Equal(u Time) bool
func (t Time) Before(u Time) bool
func (t Time) After(u Time) bool
func (t Time) Date() (year int, month Month, day int)
func (t Time) Clock() (hour, min, sec int)
func (t Time) Year() int
func (t Time) Month() Month
func (t Time) ISOWeek() (year, week int)
func (t Time) YearDay() int
func (t Time) Day() int
func (t Time) Weekday() Weekday
func (t Time) Hour() int
func (t Time) Minute() int
func (t Time) Second() int
func (t Time) Nanosecond() int
func (t Time) Add(d Duration) Time
func (t Time) AddDate(years int, months int, days int) Time
func (t Time) Sub(u Time) Duration
func (t Time) Round(d Duration) Time
func (t Time) Truncate(d Duration) Time
func (t Time) Format(layout string) string
func (t Time) String() string
func (t Time) GobEncode() ([]byte, error)
func (t *Time) GobDecode(data []byte) error
func (t Time) MarshalBinary() ([]byte, error)
func (t *Time) UnmarshalBinary(data []byte) error
func (t Time) MarshalJSON() ([]byte, error)
func (t *Time) UnmarshalJSON(data []byte) error
func (t Time) MarshalText() ([]byte, error)
func (t *Time) UnmarshalText(data []byte) error
代碼示例如下:
func main() {nowTime := time.Now()fmt.Println("nowTime.Location", nowTime.Location())zoneName, _ := nowTime.Zone()fmt.Println("nowTime.Zone", zoneName)fmt.Println("nowTime.IsZero", nowTime.IsZero())fmt.Println("nowTime.Location", nowTime.Local())fmt.Println("nowTime.UTC", nowTime.UTC())fmt.Println("nowTime.In", nowTime.In(nowTime.Location()))fmt.Println("nowTime.Unix", nowTime.Unix())fmt.Println("nowTime.UnixNano", nowTime.UnixNano())fmt.Println("nowTime.Equal", nowTime.Equal(nowTime))fmt.Println("nowTime.Before", nowTime.Before(nowTime))fmt.Println("nowTime.After", nowTime.After(nowTime))fmt.Println(nowTime.Date())fmt.Println(nowTime.Clock())fmt.Println("nowTime.Year", nowTime.Year())fmt.Println("nowTime.YearDay", nowTime.YearDay())fmt.Println("nowTime.Month", nowTime.Month())fmt.Println(nowTime.ISOWeek())fmt.Println("nowTime.Day", nowTime.Day())fmt.Println("nowTime.Weekday", nowTime.Weekday())fmt.Println("nowTime.Hour", nowTime.Hour())fmt.Println("nowTime.Minute", nowTime.Minute())fmt.Println("nowTime.Second", nowTime.Second())fmt.Println("nowTime.Nanosecond", nowTime.Nanosecond())fmt.Println("nowTime.Add", nowTime.Add(time.Hour*3))fmt.Println("nowTime.AddDate", nowTime.AddDate(2, 3, 4))fmt.Println("nowTime.Sub", nowTime.Sub(nowTime))fmt.Println("nowTime.String", nowTime.String())fmt.Println("nowTime.Format", nowTime.Format("2006-01-02 15:04:05"))fmt.Println("nowTime.Format", nowTime.Format("2006-01-02 15-04-05"))fmt.Println("nowTime.Format", nowTime.Format("2006-01-02"))}
輸出結(jié)果:
nowTime.Location Local
nowTime.Zone CST
nowTime.IsZero false
nowTime.Location 2020-05-23 15:03:24.4848344 +0800 CST
nowTime.UTC 2020-05-23 07:03:24.4848344 +0000 UTC
nowTime.In 2020-05-23 15:03:24.4848344 +0800 CST
nowTime.Unix 1590217404
nowTime.UnixNano 1590217404484834400
nowTime.Equal true
nowTime.Before false
nowTime.After false
2020 May 23
15 3 24
nowTime.Year 2020
nowTime.YearDay 144
nowTime.Month May
2020 21
nowTime.Day 23
nowTime.Weekday Saturday
nowTime.Hour 15
nowTime.Minute 3
nowTime.Second 24
nowTime.Nanosecond 484834400
nowTime.Add 2020-05-23 18:03:24.4848344 +0800 CST m=+10800.007000401
nowTime.AddDate 2022-08-27 15:03:24.4848344 +0800 CST
nowTime.Sub 0s
nowTime.String 2020-05-23 15:03:24.4848344 +0800 CST m=+0.007000401
nowTime.Format 2020-05-23 15:03:24
nowTime.Format 2020-05-23 15-03-24
nowTime.Format 2020-05-23
3. Duration 類型
type Duration int64
Duration 類型代表兩個(gè)時(shí)間點(diǎn)之間經(jīng)過(guò)的時(shí)間,以納秒為單位。
const (Nanosecond Duration = 1Microsecond = 1000 * NanosecondMillisecond = 1000 * MicrosecondSecond = 1000 * MillisecondMinute = 60 * SecondHour = 60 * Minute
)
常用的時(shí)間段。沒(méi)有定義一天或超過(guò)一天的單元,以避免夏時(shí)制的時(shí)區(qū)切換的混亂。
要將 Duration 類型值表示為某時(shí)間單元的個(gè)數(shù),用除法:
second := time.Second
fmt.Print(int64(second/time.Millisecond)) // prints 1000
要將整數(shù)個(gè)某時(shí)間單元表示為 Duration 類型值,用乘法:
seconds := 10
fmt.Print(time.Duration(seconds)*time.Second) // prints 10s
3.1 Duration 類型函數(shù)
3.1.1 func ParseDuration
func ParseDuration(s string) (Duration, error)
ParseDuration 解析一個(gè)時(shí)間段字符串。一個(gè)時(shí)間段字符串是一個(gè)序列,每個(gè)片段包含可選的正負(fù)號(hào)、十進(jìn)制數(shù)、可選的小數(shù)部分和單位后綴,如"300ms"、"-1.5h"、“2h45m”。合法的單位有"ns"、“us” /“μs”、“ms”、“s”、“m”、“h”。
3.1.2 func Since
func Since(t Time) Duration
Since 返回從 t 到現(xiàn)在經(jīng)過(guò)的時(shí)間,等價(jià)于 time.Now().Sub(t) 。
func test() {start := time.Now() // 獲取當(dāng)前時(shí)間sum := 0for i := 0; i < 100000000; i++ {sum++}elapsed := time.Since(start) // 等價(jià)于 elapsed := time.Now().Sub(start)fmt.Println("該函數(shù)執(zhí)行完成耗時(shí):", elapsed)
}
3.2 Duration 類型方法
ParseDuration 解析一個(gè)時(shí)間段字符串。一個(gè)時(shí)間段字符串是一個(gè)序列,每個(gè)片段包含可選的正負(fù)號(hào)、十進(jìn)制數(shù)、可選的小數(shù)部分和單位后綴,如"300ms"、"-1.5h"、“2h45m”。
合法的單位有"ns"、“us”、“μs”、“ms”、“s”、“m”、“h”。
func (d Duration) Hours() float64
func (d Duration) Minutes() float64
func (d Duration) Seconds() float64
func (d Duration) Nanoseconds() int64
func (d Duration) String() string
代碼示例:
func main() {tp, _ := time.ParseDuration("120s")fmt.Println("tp.Hours", tp.Hours()) // tp.Hours 0.03333333333333333fmt.Println("tp.Minutes", tp.Minutes()) // tp.Minutes 2fmt.Println("tp.Seconds", tp.Seconds()) // tp.Seconds 120fmt.Println("tp.Nanoseconds", tp.Nanoseconds()) // tp.Nanoseconds 120000000000fmt.Println("tp.String", tp.String()) // tp.String 2m0s
}
4. Location 類型
func LoadLocation(name string) (*Location, error)
func FixedZone(name string, offset int) *Location
func (l *Location) String() string
代碼示例:
func main() {loc, _ := time.LoadLocation("")// 服務(wù)器設(shè)定的時(shí)區(qū),一般為CSTloc, _ = time.LoadLocation("Local")fmt.Println("loc is ", loc) // loc is Local// 美國(guó)洛杉磯PDTloc, _ = time.LoadLocation("America/Los_Angeles")fmt.Println("loc is ", loc) // loc is America/Los_Angeles// 獲取指定時(shí)區(qū)的時(shí)間點(diǎn)local, _ := time.LoadLocation("America/Los_Angeles")fmt.Println(time.Date(2018, 1, 1, 12, 0, 0, 0, local)) //2018-01-01 12:00:00 -0800 PST}
5. 實(shí)際業(yè)務(wù)使用場(chǎng)景
5.1 獲取時(shí)、分、秒的單位值
const (Nanosecond Duration = 1Microsecond = 1000 * NanosecondMillisecond = 1000 * MicrosecondSecond = 1000 * MillisecondMinute = 60 * SecondHour = 60 * Minute
)
源碼包定義以上常量,在代碼中可以通過(guò) time.XXX 得到,代碼如下:
func main() {fmt.Println("time.Nanosecond", time.Nanosecond) // time.Nanosecond 1nsfmt.Println("time.Microsecond", time.Microsecond) // time.Microsecond 1μsfmt.Println("time.Millisecond", time.Millisecond) // time.Millisecond 1msfmt.Println("time.Second", time.Second) // time.Second 1sfmt.Println("time.Minute", time.Minute) // time.Minute 1m0sfmt.Println("time.Hour", time.Hour) // time.Hour 1h0m0s
}
5.2 標(biāo)準(zhǔn)時(shí)間和Unix時(shí)間轉(zhuǎn)換
代碼如下:
func main() {timeNow := time.Now()fmt.Println("timeNow is ", timeNow)// timeNow is 2020-05-23 22:29:53.0060736 +0800 CST m=+0.005000301timeUnix := timeNow.Unix()fmt.Println("timeUnix is ", timeUnix)// timeUnix is 1590244193timeCurrent := time.Unix(timeUnix, 0)fmt.Println("timeCurrent is ", timeCurrent)// timeCurrent is 2020-05-23 22:29:53 +0800 CST}
5.3 Time 類型轉(zhuǎn)換為字符串
注意: Go 中指定的特定時(shí)間格式為 2006-01-02 15:04:05 -0700 MST , 為了記憶方便,按照美式時(shí)間格式 月日時(shí)分秒年 外加時(shí)區(qū) 排列起來(lái)依次是 01/02 03:04:05PM ‘06 -0700,剛開(kāi)始使用時(shí)需要注意。
這一點(diǎn)與 Python 中的 %Y-%m-%d %H-%M-%S 有區(qū)別。
示例代碼:
const (//time formatFormatDay = "2006-01-02"FormatSecond = "2006-01-02 15:04:05"FormatMinute = "2006-01-02 15:04"FormatOnlyHour = "15:04"
)func main() {timeFormatDay := time.Now().Format(FormatDay)fmt.Printf("timeFormatDay is %#v, type is %T\n", timeFormatDay, timeFormatDay)// timeFormatDay is "2020-05-23", type is stringtimeFormatSecond := time.Now().Format(FormatSecond)fmt.Println("timeFormatSecond is ", timeFormatSecond)// timeFormatSecond is 2020-05-23 22:44:26timeFormatMinute := time.Now().Format(FormatMinute)fmt.Println("timeFormatMinute is ", timeFormatMinute)// timeFormatMinute is 2020-05-23 22:44timeFormatOnlyHour := time.Now().Format(FormatOnlyHour)fmt.Println("timeFormatOnlyHour is ", timeFormatOnlyHour)// timeFormatOnlyHour is 22:44}
5.4 字符串轉(zhuǎn)換為T(mén)ime類型
代碼如下:
const (//time formatFormatDay = "2006-01-02"FormatSecond = "2006-01-02 15:04:05"FormatMinute = "2006-01-02 15:04"FormatOnlyHour = "15:04"
)func main() {timestamp, _ := time.Parse(FormatSecond, "2020-05-23 22:20:30")fmt.Printf("timestamp is %v, type is %T\n", timestamp, timestamp)// timestamp is 2020-05-23 22:20:30 +0000 UTC, type is time.Timefmt.Println(timestamp.Unix()) //時(shí)間戳 1590272430fmt.Println(time.Date(2020, 05, 23, 10, 11, 12, 13, time.Local).Unix())}
5.5 時(shí)區(qū)變更后獲取時(shí)間戳
示例代碼:
const (//time formatFormatDay = "2006-01-02"FormatSecond = "2006-01-02 15:04:05"FormatMinute = "2006-01-02 15:04"FormatOnlyHour = "15:04"
)func main() {loc, _ := time.LoadLocation("Asia/Shanghai")t, _ := time.ParseInLocation(FormatSecond, "2020-05-23 22:20:30", loc)fmt.Printf("t is %v, type is %T\n", t, t)// 標(biāo)準(zhǔn)時(shí)間格式 t is 2020-05-23 22:20:30 +0800 CST, type is time.Timefmt.Println(t.Unix()) //時(shí)間戳 1590243630}
5.6 比較兩個(gè)時(shí)間點(diǎn)
dt := time.Date(2018, 1, 10, 0, 0, 1, 100, time.Local)fmt.Println(time.Now().After(dt)) // truefmt.Println(time.Now().Before(dt)) // false// 是否相等 判斷兩個(gè)時(shí)間點(diǎn)是否相等時(shí)推薦使用 Equal 函數(shù)fmt.Println(dt.Equal(time.Now()))
5.7 時(shí)區(qū)之間轉(zhuǎn)換
// time.Local 用來(lái)表示當(dāng)前服務(wù)器時(shí)區(qū)// 自定義地區(qū)時(shí)間secondsEastOfUTC := int((8 * time.Hour).Seconds())beijing := time.FixedZone("Beijing Time", secondsEastOfUTC)fmt.Println(time.Date(2018,1,2,0,0,0,0, beijing)) // 2018-01-02 00:00:00 +0800 Beijing Time // 當(dāng)前時(shí)間轉(zhuǎn)為指定時(shí)區(qū)時(shí)間fmt.Println(time.Now().In(beijing))// 指定時(shí)間轉(zhuǎn)換成指定時(shí)區(qū)對(duì)應(yīng)的時(shí)間dt, err := time.ParseInLocation("2006-01-02 15:04:05", "2017-05-11 14:06:06", time.Local)// 當(dāng)前時(shí)間在零時(shí)區(qū)年月日 時(shí)分秒 時(shí)區(qū)year, mon, day := time.Now().UTC().Date() // 2018 April 24 hour, min, sec := time.Now().UTC().Clock() // 3 47 15zone, _ := time.Now().UTC().Zone() // UTC
5.8 基于當(dāng)前時(shí)間的加減
now := time.Now()// 一年零一個(gè)月一天之后fmt.Println(now.Date(1,1,1))// 一段時(shí)間之后fmt.Println(now.Add(time.Duration(10)*time.Minute))// 計(jì)算兩個(gè)時(shí)間點(diǎn)的相差天數(shù)dt1 = time.Date(dt1.Year(), dt1.Month(), dt1.Day(), 0, 0, 0, 0, time.Local)dt2 = time.Date(dt2.Year(), dt2.Month(), dt2.Day(), 0, 0, 0, 0, time.Local)fmt.Println(int(math.Ceil(dt1.Sub(dt2).Hours() / 24)))
5.9 時(shí)間差值
dt1 := time.Date(2018, 1, 10, 0, 0, 1, 100, time.Local)dt2 := time.Date(2018, 1, 9, 23, 59, 22, 100, time.Local)// 不用關(guān)注時(shí)區(qū),go會(huì)轉(zhuǎn)換成時(shí)間戳進(jìn)行計(jì)算fmt.Println(dt1.Sub(dt2))
5.10 時(shí)間運(yùn)算
// func Sleep(d Duration) 休眠多少時(shí)間,休眠時(shí)處于阻塞狀態(tài),后續(xù)程序無(wú)法執(zhí)行time.Sleep(time.Duration(10) * time.Second)// func After(d Duration) <-chan Time 非阻塞,可用于延遲time.After(time.Duration(10) * time.Second)// func Since(t Time) Duration 兩個(gè)時(shí)間點(diǎn)的間隔start := time.Now()fmt.Println(time.Since(start)) // 等價(jià)于 Now().Sub(t), 可用來(lái)計(jì)算一段業(yè)務(wù)的消耗時(shí)間func Until(t Time) Duration // 等價(jià)于 t.Sub(Now()),t與當(dāng)前時(shí)間的間隔// func (t Time) Add(d Duration) Timefmt.Println(dt.Add(time.Duration(10) * time.Second)) // 加func (t Time) Sub(u Time) Duration // 減 // func (t Time) AddDate(years int, months int, days int) Timefmt.Println(dt.AddDate(1, 1, 1))func (t Time) Before(u Time) boolfunc (t Time) After(u Time) boolfunc (t Time) Equal(u Time) bool 比較時(shí)間點(diǎn)時(shí)盡量使用Equal函數(shù)
6. time.After 一段時(shí)間后
由于 Go 語(yǔ)言中的通道和 goroutine 的設(shè)計(jì),定時(shí)任務(wù)可以在 goroutine 中通過(guò)同步的方式完成,也可以通過(guò)在 goroutine 中異步回調(diào)完成。
- 同步調(diào)用
func doTask() {fmt.Println("I am running")
}
func main() {// 定時(shí)器超時(shí)之后,執(zhí)行后的的函數(shù)time.AfterFunc(time.Duration(3)*time.Second, doTask)time.Sleep(10 * time.Second)
}
- 異步調(diào)用
func main() {// 聲明一個(gè)退出用的通道exit := make(chan int)fmt.Println("start")// 調(diào)用 time.AfterFunc()函數(shù),傳入等待的時(shí)間和一個(gè)回調(diào)。回調(diào)使用一個(gè)// 匿名函數(shù),在時(shí)間到達(dá)后, 匿名函數(shù)會(huì)在另外一個(gè) goroutine 中被調(diào)用。time.AfterFunc(time.Second, func() {// 1秒后,打印結(jié)果fmt.Println("one second after")// 通知main的goroutine已經(jīng)結(jié)束exit <- 0})// 等待結(jié)束<-exit
}
time.AfterFunc 函數(shù)是在 time.After 基礎(chǔ)上增加了到時(shí)的回調(diào),方便使用。而 time.After 函數(shù)又是在 time.NewTimer() 函數(shù)上進(jìn)行的封裝。
7. 定點(diǎn)計(jì)時(shí)
- 計(jì)時(shí)器(
Timer)的原理和倒計(jì)時(shí)鬧鐘類似,都是給定多少時(shí)間后觸發(fā)。 - 打點(diǎn)器(
Ticker)的原理和鐘表類似,鐘表每到整點(diǎn)就會(huì)觸發(fā)。
這兩種方法創(chuàng)建后會(huì)返回time.Timer 對(duì)象和 time.Ticker 對(duì)象,里面通過(guò)一個(gè) C 成員 , 類型是只能接收的時(shí)間通道 C <-chan Time ),使用這個(gè)通道就可以 獲得時(shí)間觸發(fā)的通知。
使用 time.Ticker 可讓代碼每隔特定的時(shí)間就重復(fù)執(zhí)行一次。需要在很長(zhǎng)的時(shí)間內(nèi)定期執(zhí)行任務(wù)時(shí),這么做很有用。
示例代碼 1:
func main() {// 定時(shí)休眠 1sFormatSecond := "2006-01-02 15:04:05"for {select {case <-time.NewTimer(1 * time.Second).C: // 將在1秒可讀,返回fmt.Println(time.Now().Format(FormatSecond), "sleep 1s")}}
}
輸出結(jié)果:
2021-04-19 14:12:59 sleep 1s
2021-04-19 14:13:00 sleep 1s
2021-04-19 14:13:01 sleep 1s
2021-04-19 14:13:02 sleep 1s
2021-04-19 14:13:03 sleep 1s
2021-04-19 14:13:04 sleep 1s
2021-04-19 14:13:05 sleep 1s
示例代碼 2:
package mainimport ("fmt""time"
)func main() {// 創(chuàng)建一個(gè)計(jì)時(shí)器,2秒后觸發(fā)stopper := time.NewTimer(time.Second * 2)// 創(chuàng)建一個(gè)斷續(xù)器,每500毫秒觸發(fā)一次ticker := time.NewTicker(time.Millisecond * 500)var i int// 每次觸發(fā)后 select會(huì)結(jié)束, 需要使用循環(huán)再次從打點(diǎn)器返回的通道中獲取觸發(fā)通知for {// 多路復(fù)用通道 同時(shí)等待多路計(jì)時(shí)器信號(hào)select {case <-stopper.C: // 計(jì)時(shí)器到時(shí)了fmt.Println("stop")// 跳出循環(huán)goto StopHerecase <-ticker.C: // 斷續(xù)器觸發(fā)了// 記錄觸發(fā)了多少次i++fmt.Println("tick", i)}}// 退出的標(biāo)簽,使用goto跳轉(zhuǎn)
StopHere:fmt.Println("done")
}
輸出結(jié)果:
tick 1
tick 2
tick 3
stop
done
參考:
https://segmentfault.com/a/1190000015040923?utm_source=tag-newest
https://blog.csdn.net/wschq/article/details/80114036
https://studygolang.com/static/pkgdoc/pkg/time.htm
https://blog.csdn.net/duqiming/article/details/89393812
總結(jié)
以上是生活随笔為你收集整理的Go 学习笔记(48)— Go 标准库之 time (获取时/分/秒的单位值、标准时间和Unix时间转换、字符串时间和Time类型转换、时区转换、时间的加减/休眠)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 求一个霸气女王范个性签名
- 下一篇: 上门开锁一般要多少钱