golang中的标准库time
阅读原文时间:2022年04月06日阅读:1

时间类型

time.Time类型表示时间。我们可以通过time.Now()函数获取当前的时间对象,然后获取时间对象的年月日时分秒等信息。示例代码如下:

func main() {
    current := time.Now()
    fmt.Println(current)
    // 2021-11-26 16:13:54.3960877 +0800 CST m=+0.011114601

    // 将时间类型转换成字符串类型
    strCurrent := current.Format("2006-01-02 15:04:05")
    fmt.Println(strCurrent)  // 2021-11-26 16:18:23 +0000 UTC

    // 字符串类型转换成时间类型
    timeCurrent, _ := time.Parse("2006-01-02 15:04:05", strCurrent)
    fmt.Println(timeCurrent)  // 2021-11-26 16:18:23 +0000 UTC

    // 获取年月日、时分秒中的单个int值,month是Month类型,Month是自定义的int类型
    year := current.Year()
    month := current.Month()
    day := current.Day()
    hour := current.Hour()
    minute := current.Minute()
    second := current.Second()
    fmt.Printf("%d-%2d-%2d %2d:%2d:%2d\n", year, month, day, hour, minute, second)
    // 2021-11-26 16:13:54

}

时间戳

时间戳是自1970年1月1日(08:00:00GMT)至当前时间的总毫秒数。它也被称为Unix时间戳(UnixTimestamp)。

  1. 基于时间对象获取时间戳的示例代码如下:

    func main() {
    now := time.Now()
    timestamp1 := now.Unix() // 秒
    timestamp2 := now.UnixMilli() // 毫秒
    timestamp3 := now.UnixMicro() // 微秒
    timestamp4 := now.UnixNano() // 纳秒

    fmt.Println(timestamp1)  // 1637915082
    fmt.Println(timestamp2)
    fmt.Println(timestamp3)
    fmt.Println(timestamp4)  // 1637915082773954700

    }

  2. 使用time.Unix()函数可以将时间戳转为时间格式。

    func main() {
    now := time.Now()
    fmt.Println(now) // 2021-11-26 16:31:22.4630069 +0800 CST m=+0.011961601
    timestamp1 := now.Unix() // 时间戳秒

    current := time.Unix(timestamp1, 0)  // 将时间戳转换为时间格式
    fmt.Println(current)  // 2021-11-26 16:30:53 +0800 CST

    }

时间操作

Add

我们在日常的编码过程中可能会遇到要求时间+时间间隔的需求,Go语言的时间对象有提供Add方法如下:

func main() {
    now := time.Now()
    ret := now.Add(time.Hour + 30 * time.Minute)  // 计算一个半小时以后的时间
    fmt.Println(ret)
}

Sub

求两个时间之间的差值:

func main() {
    now := time.Now()
    endTime := now.Add(time.Hour + 30 * time.Minute)  // 计算一个半小时以后的时间

    duration := endTime.Sub(now)  // 计算时间差
    fmt.Println(duration)  // 输出:1h30m0s
}

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

Equal

func main() {
    now := time.Now()
    endTime := now.Add(time.Hour + 30 * time.Minute)  // 计算一个半小时以后的时间
    now2 := time.Now()

    // 比较两个时间是否相等
    boo := endTime.Equal(now)
    boo2 := now2.Equal(now)
    fmt.Println(boo, boo2)  // false true
}

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

Before

func main() {
    now := time.Now()
    end := now.Add(time.Second)

    boo1 := now.Before(end)
    fmt.Println(boo1)  // true

    boo2 := end.Before(now)
    fmt.Println(boo2)  // false
}

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

After

func (t Time) After(u Time) bool

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

定时器

使用time.Tick(时间间隔)来设置定时器,定时器的本质上是一个通道(channel)

  1. 方法一:

    func main() {
    // 使用time.Tick时间间隔来设置定时器,定时器的本质是一个通道channel
    ticker := time.Tick(time.Second) // 定义一个1秒间隔的定时器
    for i := range ticker {
    fmt.Println(i.Format("2006-01-02 15:04:05")) // 每格一秒执行一次任务
    }
    }

输出结果:

2021-11-29 10:01:36

2021-11-29 10:01:37

2021-11-29 10:01:38

  1. 方法二:

    func main() {
    // 使用time.Tick时间间隔来设置定时器,定时器的本质是一个通道channel
    ticker := time.NewTicker(time.Second * 2)
    for i := range ticker.C {
    fmt.Println(i.Format("2006-01-02 15:04:05"))
    }
    }

时间格式化

时间类型有一个自带的方法Format进行格式化,需要注意的是Go语言中格式化时间模板不是常见的Y-m-d H:M:S而是使用Go的诞生时间2006年1月2号15点04分(记忆口诀为2006 1 2 3 4)。也许这就是技术人员的浪漫吧。

补充:如果想格式化为12小时方式,需指定PM。

func main() {
    now := time.Now()
    fmt.Println(now.Format("2006-01-02 15:04:05 Mon Jan"))  // 24小时制
    // 2021-11-29 10:17:00 Mon Nov
    fmt.Println(now.Format("03:04:05 2006/01/02 PM Mon Jan"))  // 12小时制
    // 10:17:00 2021/11/29 AM Mon Nov
    fmt.Println(now.Format("2006-01-02"))
    // 2021-11-29
}

解析字符串格式的时间

func main() {
    // 解析字符串格式的时间
    now := time.Now()
    fmt.Println(now)
    // 加载时区
    loc, err := time.LoadLocation("Asia/Shanghai")
    if err != nil {
        fmt.Println(err.Error())
        return
    }
    // 按照指定时区和指定格式解析字符串时间
    timeObj, err := time.ParseInLocation("2006/01/02 15:04:05", "2021/11/28 23:59:59", loc)
    if err != nil {
        fmt.Println(err.Error())
        return
    }
    fmt.Println(timeObj)
    fmt.Println(now.Sub(timeObj))
}

输出结果:

2021-11-29 10:39:02.8339716 +0800 CST m=+0.010589201

2021-11-28 23:59:59 +0800 CST

10h39m3.8339716s