Go语言中,对时间的处理的函数位于time包。

一、基础时间处理

1、获取当前时间戳

  1. // 获取当前时间戳
  2. t := time.Now().Unix()
  3. fmt.Println(t)
  4. // 结果:1617442213

2、将时间戳格式化为时间字符串

  1. // 将给定时间戳 格式化为 时间字符串
  2. t1 := int64(1617442213)
  3. ts := time.Unix(t1, 0).Format("2006-01-02 15:04:05")
  4. fmt.Println(ts)
  5. // 结果:2021-04-03 17:30:13
  6. // 获取当前时间戳 的时间字符串
  7. ts2 := time.Now().Format("2006年01月02日 15时04分05秒")
  8. fmt.Println(ts2)
  9. // 结果:2021年04月03日 17时40分53秒
  • 1、需要注意的是,这里调用Format()函数进行时间戳的格式化的时候,其中传入的格式化参数是2006-01-02 15:04:05,该参数即为其他语言中的Y-m-d H:i:s。 ```go Y - m - d H :i :s 2006 - 01 - 02 15:04:05

2006 代表年份 即Y 01 代表月份 即m 02 代表日期 即d 15 代表小时 即H 04 代表分钟 即i 05 代表秒数 即s

  1. - 2、上面的这里 `time.Now().Unix()`和下面的 `time.Unix()` 不是一个东西,不要搞混了。前者是获取`Unix`时间戳,后者是将一个时间戳转化为`Time`结构体对象。
  2. 也就是说,将一个时间戳转化为Time结构体对象的方法为:
  3. ```go
  4. t := int64(1617442213)
  5. tObj := time.Unix(t, 0)
  6. // 此时 tObj就是一个Time结构体对象了,类型和time.Now()的一样。

3、将时间字符串转化为时间戳

将时间字符串转为时间戳的关键是指定时区。

  1. // 指定时区
  2. loc, err := time.LoadLocation("PRC") //或者用 Asia/shanghai
  3. if err != nil {
  4. fmt.Println(err)
  5. return
  6. }
  7. // 将 2021-04-03 17:30:13 转化为时间对象
  8. tm, err := time.ParseInLocation("2006-01-02 15:04:05", "2021-04-03 17:30:13", loc)
  9. if err != nil {
  10. fmt.Println(err)
  11. return
  12. }
  13. // 转化为时间戳
  14. t := tm.Unix()
  15. fmt.Println("结果:", t)
  16. // 结果:1617442213

4、指定具体时间

Go语言提供有方法直接指定具体时间,返回Time结构体对象

  1. //loc, _ := time.LoadLocation("PRC")
  2. t := time.Date(2021, 4, 4, 12, 01, 02, 0, time.Local)
  3. fmt.Println(t)
  4. // 2021-04-04 12:01:02 +0800 CST

注意上面的time.Date()函数里最后一个参数为指定时区,这里虽然我们指定了本地时区,但是我还是建议多写一步,手动指定下时区,不要用本地默认时区。
因为在服务器层面,可能本地时区没有设置,默认为UTC,导致时间计算错误。

二、时间计算

1、对时间进行增加的操作:Add()

  1. // 首先获取当前时间
  2. now := time.Now()
  3. //在当前时间的基础上 增加1小时
  4. addNow := now.Add(time.Hour)
  5. fmt.Println("当前时间是: ", now.Format("2006-01-02 15:04:05"))
  6. fmt.Println("add后的时间是:", addNow.Format("2006-01-02 15:04:05"))
  7. //当前时间是: 2021-04-03 18:30:39
  8. //add后的时间是: 2021-04-03 19:30:39

Add()方法的参数为Duration格式数字:type Duration int64
Add()方法的参数使用time包提供好的常量最为清晰:

  1. const (
  2. Nanosecond Duration = 1
  3. Microsecond = 1000 * Nanosecond
  4. Millisecond = 1000 * Microsecond
  5. Second = 1000 * Millisecond
  6. Minute = 60 * Second
  7. Hour = 60 * Minute
  8. )

time.Hour 就代表1小时,5 * time.Hour 就代表5小时。

2、两个时间求差:Sub()

  1. // 首先获取当前时间
  2. now := time.Now()
  3. //在当前时间的基础上 增加1小时
  4. addNow := now.Add(time.Hour)
  5. //两个时间求差
  6. sub := now.Sub(addNow)
  7. fmt.Println("now和addNow相差秒数:", sub.Seconds())
  8. // 结果:now和addNow相差秒数: -3600

3、判断两个时间是否相等:Equal()

比较两个时间是否相等应该使用Equal()方法。

  1. // 首先获取当前时间
  2. now := time.Now()
  3. //在当前时间的基础上 增加1小时
  4. addNow := now.Add(time.Hour)
  5. // 比较两个时间
  6. is := now.Equal(addNow)
  7. fmt.Println("now和addNow是否相等:", is)
  8. // 结果:now和addNow是否相等: false

4、判断两个时间的前后:befer()和after()

  1. // 首先获取当前时间
  2. now := time.Now()
  3. //在当前时间的基础上 增加1小时
  4. addNow := now.Add(time.Hour)
  5. // now是否在addNow之前
  6. isBef := now.Before(addNow)
  7. fmt.Println(isBef) //true
  8. // now是否在addNow之后
  9. isAft := now.After(addNow)
  10. fmt.Println(isAft) //false

三、其他时间相关方法

1、time.Sleep()阻塞休眠

  1. time.Sleep(time.Second * 2)

以上,程序将阻塞2秒后继续向下执行。

2、time.After()延后时间

  1. 调用time.After(duration),此函数马上返回,返回一个time.Time类型的Chan,不阻塞。
  2. 后面你该做什么做什么,不影响。到了duration时间后,自动塞一个当前时间进去。
  3. 你可以阻塞的等待,或者晚点再取。
  4. 因为底层是用NewTimer实现的,所以如果考虑到效率低,可以直接自己调用NewTimer
  1. tChan := time.After(time.Second * 3)
  2. // 打印tChan类型
  3. fmt.Printf("tChan type=%T\n", tChan)
  4. fmt.Println("执行中1......")
  5. fmt.Println("tChan =", <-tChan)
  6. fmt.Println("执行中2......")
  7. //将会先打印前两个,阻塞等待chan中元素弹出后,再打印后两个

3、time.Tick()定时器

  1. tick := time.Tick(time.Second * 2)
  2. for i := range tick {
  3. fmt.Println(i)
  4. }
  5. //每2秒打印一个时间:
  6. 2021-04-03 19:55:20.074067 +0800 CST m=+2.003403052
  7. 2021-04-03 19:55:22.07663 +0800 CST m=+4.005945208
  8. 2021-04-03 19:55:24.071302 +0800 CST m=+6.000595846
  9. 2021-04-03 19:55:26.071829 +0800 CST m=+8.001102100
  10. 2021-04-03 19:55:28.071312 +0800 CST m=+10.000563192
  11. ...