• Golang time模块常用示例


    本文就不对官方文档做详细解析了,只贴一些常用的示例。如需查看官网点击上述链接即可。

    一、时间的加减以及格式化示例:

    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))
    		}
    	}
    }
    

      

    想建一个数据库技术和编程技术的交流群,用于磨炼提升技术能力,目前主要专注于Golang和Python以及TiDB,MySQL数据库,群号:231338927,建群日期:2019.04.26,截止2021.02.01人数:300人 ... 如发现博客错误,可直接留言指正,感谢。
  • 相关阅读:
    暑期测试训练3
    对于在线段树上修改整段区间的理解
    UVA 11090 判负圈问题
    ZOJ 2588 求割边问题
    POJ 1523 网络连通
    hdu 1163
    hdu 1703
    hdu 2577 模拟
    hdu 3836 强连通+缩点:加边构强连通
    hdu 2571
  • 原文地址:https://www.cnblogs.com/realcp1018/p/15634207.html
Copyright © 2020-2023  润新知