本文就不对官方文档做详细解析了,只贴一些常用的示例。如需查看官网点击上述链接即可。
一、时间的加减以及格式化示例:
func main() { s := time.Now().Add(time.Hour * -2) now := fmt.Sprintf("%04d-%02d-%02d %02d:%02d:%02d", s.Year(), s.Month(), s.Day(), s.Hour(), s.Minute(), s.Second()) fmt.Println(now) }
二、通过time.Date()和time.Parse(),time.Unix()快速构造time.Time类型
t := time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC) t, err := time.Parse(time.RFC3339, "2009-10-23T12:04:05+08:00") // 此处需注意,虽然time.RFC3339展示的时区前缀为Z,但实际使用时使用+号才有效,使用Z会错误解析为0000-01-01 00:00:00 +0000 UTC t := time.Unix(<epoch time second>, 0) t := time.UnixMicro(<epoch time microsecond>) t := time.UnixMilli(<epoch time millisecond>) // epoch time即unix time
三、通过time.Since()快速的计算到当前的时间
time.Since(u time)可以实现时间的快速计算,得到一个可打印的、易于人眼识别的time.Duration类型。其相当于time.Now().Sub(t)。
t, _ = time.Parse(time.RFC3339, "2020-09-30T11:04:05+08:00") fmt.Println(time.Since(t)) // 打印结果为2h28m1.0416486s
四、时间乘法
time.Second/Hour等可以直接与数字相乘,但不能直接与数字类型的变量相乘.......这是一个很不合理、很反直觉的设计,目前只能接受,未来go团队可能改进。
变通办法为使用time.Duration将数字变量转化为一个time.Duration类型,这样就可以与time.Second相乘了。例如:
time.Since(startTime) > time.Duration(24 * time.Hour * time.Duration(bc.KeepDays))
time.Second就是Duration类型,而time.Duration本质上是一个int64的数字。可以将time.Duration(数字)得到的结果看作时间计量值,乘以对应的时间单位后得到一个具体的时间长度。
五、有用的计时channel
很多时候我们需要为某个/多个任务计时,或者有每隔几秒打印日志等待任务执行完毕的需求。time包提供了实现此类需求的简易channel。
使用time.After()和time.NewTicker可以便捷的构造相关时间等待的channel和对象,接下来看两个简单示例:
func test(done chan<- bool) { time.Sleep(2 * time.Second) done <- true } func main() { timeOutSec := 5 timeOutChan := time.After(time.Second * time.Duration(timeOutSec)) // 开启一个goroutine,检测其是5秒否超时 testDoneChan := make(chan bool) go test(testDoneChan) select { case <- testDoneChan: fmt.Println("Test Done!") case <- timeOutChan: fmt.Println("Test Time Out!") return } } // 如果需要同时检测多个子任务,可以把他们的doneChan放入一个waitGroup中,然后开启一个单独的goroutine和chan等待wg.Wait()完毕后写入chan。之后通过select这个chan来判断所有任务是否都已执行完毕。
func test(done chan<- bool) { time.Sleep(10 * time.Second) done <- true } func main() { ticker := time.NewTicker(time.Second * 2) defer ticker.Stop() // 开启一个goroutine,每2秒tick一次直到test执行完 testDoneChan := make(chan bool) go test(testDoneChan) for { select { case <- testDoneChan: fmt.Println("Test Done!") return case t := <- ticker.C: fmt.Println("Current time:", t.Format(time.RFC3339)) } } }