Go时间包

一、简介

go 语言中使用time.Time表示时间。我们可以通过time.Now函数获取当前的时间对象,然后从时间对象中可以获取到年、月、日、时、分、秒等信息。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package main

import (
"fmt"
"time"
)

func main() {
t := time.Now() // 获取当前时间
fmt.Printf("当前时间:%v\n", t)
fmt.Println("年", t.Year())
fmt.Println("月", t.Month())
fmt.Println("日", t.Day())
fmt.Println("时", t.Hour())
fmt.Println("分", t.Minute())
fmt.Println("秒", t.Second())
}

输出:

1
2
3
4
5
6
当前时间:2022-05-19 21:38:39.7367663 +0800 CST m=+0.001805001
2022
月 May
19
21
38

二、常量

time 包中定义的时间间隔类型的常量如下:

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

例如:time.Hour表示1小时,time.Second表示1秒。

三、func (t Time) Add(d Duration) Time

求一个小时之后的时间:

1
2
3
4
5
func main() {
now := time.Now()
later := now.Add(time.Hour) // 当前时间加1小时后的时间
fmt.Println(later)
}

四、func (t Time) Sub(u Time) Duration

求两个时间之间的差值:
返回一个时间段t-u。如果结果超出了Duration可以表示的最大值/最小值,将返回最大值/最小值。要获取时间点t-d(d为Duration),可以使用t.Add(-d)。
例如

1
2
3
t := time.Now()
later := t.Add(time.Hour) // 当前时间加1小时后的时间
fmt.Println(later.Sub(t))//一个小时后的时间与现在时间差

输出:

1
1h0m0s

五、func (t Time) Equal(u Time) bool

判断两个时间是否相同,会考虑时区的影响,因此不同时区标准的时间也可以正确比较。本方法和用t==u不同,这种方法还会比较地点和时区信息。

六、func (t Time) Before(u Time) bool

如果t代表的时间点在u之前,返回真;否则返回假。

七、func (t Time) After(u Time) bool

如果t代表的时间点在u之后,返回真;否则返回假。

八、time.Format

time.Format函数能够将一个时间对象格式化输出为指定布局的文本表示形式,需要注意的是 Go 语言中时间格式化的布局不是常见的Y-m-d H:M:S,而是使用 2006-01-02 15:04:05.000

其中:

1
2
3
4
5
6
2006:年(Y)
01:月(m)
02:日(d)
15:时(H)
04:分(M)
05:秒(S)

————————-补充————————–
如果想格式化为12小时格式,需在格式化布局中添加PM。
小数部分想保留指定位数就写0,如果想省略末尾可能的0就写 9。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// formatDemo 时间格式化
func formatDemo() {
now := time.Now()
// 格式化的模板为 2006-01-02 15:04:05

// 24小时制
fmt.Println(now.Format("2006-01-02 15:04:05.000 Mon Jan"))
// 12小时制
fmt.Println(now.Format("2006-01-02 03:04:05.000 PM Mon Jan"))

// 小数点后写0,因为有3个0所以格式化输出的结果也保留3位小数
fmt.Println(now.Format("2006/01/02 15:04:05.000")) // 2022/02/27 00:10:42.960
// 小数点后写9,会省略末尾可能出现的0
fmt.Println(now.Format("2006/01/02 15:04:05.999")) // 2022/02/27 00:10:42.96

// 只格式化时分秒部分
fmt.Println(now.Format("15:04:05"))
// 只格式化日期部分
fmt.Println(now.Format("2006.01.02"))
}

九、解析字符串格式的时间

对于从文本的时间表示中解析出时间对象,time包中提供了time.Parse和time.ParseInLocation两个函数。

  1. time.Parse在解析时不需要额外指定时区信息。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// parseDemo 指定时区解析时间
func parseDemo() {
// 在没有时区指示符的情况下,time.Parse 返回UTC时间
timeObj, err := time.Parse("2006/01/02 15:04:05", "2022/10/05 11:25:20")
if err != nil {
fmt.Println(err)
return
}
fmt.Println(timeObj) // 2022-10-05 11:25:20 +0000 UTC

// 在有时区指示符的情况下,time.Parse 返回对应时区的时间表示
// RFC3339 = "2006-01-02T15:04:05Z07:00"
timeObj, err = time.Parse(time.RFC3339, "2022-10-05T11:25:20+08:00")
if err != nil {
fmt.Println(err)
return
}
fmt.Println(timeObj) // 2022-10-05 11:25:20 +0800 CST
}
  1. time.ParseInLocation函数需要在解析时额外指定时区信息。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    // parseDemo 解析时间
    func parseDemo() {
    now := time.Now()
    fmt.Println(now)
    // 加载时区
    loc, err := time.LoadLocation("Asia/Shanghai")
    if err != nil {
    fmt.Println(err)
    return
    }
    // 按照指定时区和指定格式解析字符串时间
    timeObj, err := time.ParseInLocation("2006/01/02 15:04:05", "2022/10/05 11:25:20", loc)
    if err != nil {
    fmt.Println(err)
    return
    }
    fmt.Println(timeObj)
    fmt.Println(timeObj.Sub(now))
    }