分享

time 时间和日期相关方法

 菜籽爱编程 2022-04-27

在编程中,我们经常会使用到时间和日期相关的方法,这一期我们就来看一看在 Go 中的时间和日期相关的方法。使用 Go 中的时间和日期相关的方法,需要引入 time 包。


time.Time 类型

在 Go 中,time.Time 类型用于表示时间。

type Time struct {
 wall uint64
 ext  int64
 loc *Location
}

time.Time 代表一个纳秒精度的时间点。程序中应使用 time.Time 类型值来保存和传递时间,而不能用指针。time.Time 类型值可以被多个 goroutine 同时使用。时间点可以使用 Before()After()Equal() 方法进行比较。Sub() 方法让两个时间点相减,生成一个 Duration 类型值(代表时间段)。Add() 方法给一个时间点加上一个时间段,生成一个新的 time.Time 类型时间点。

从上面的源码我们知道,每一个 time.Time 都具有一个地点信息(及对应地点的时区信息),当计算时间的表示格式时,如 Format()Hour()Year() 等方法,都会考虑该信息。Local()UTC()In() 方法返回一个指定时区(但指向同一时间点)的 time.Time 。修改地点/时区信息只是会改变其表示;不会修改被表示的时间点,因此也不会影响其计算。


获取当前本地时间

使用 time.Now() 方法我们可以获取当前本地时间:

// Now returns the current local time.
func Now() Time {...}

例如:

package main

import (
 "fmt"
 "time"
)

func main() {
 fmt.Println(time.Now())
}

运行上面的程序会输出当前本地时间:

2022-03-03 21:57:39.5130486 +0800 CST m=+0.010532401


获取到日期的其他信息

使用下面的一些方法我们能获取到日期的特定信息:

  • time.Date():获取时间点 time 对应的年、月、日。
  • time.Clock():获取时间点 time 对应的那一天的时、分、秒。
  • time.Year():获取时间点 time 对应的年份。
  • time.Month():获取时间点 time 对应那一年的月份。
  • time.Day():获取时间点 time 对应那一月的第几日。
  • time.ISOWeek():获取时间点 time 对应的 ISO 9601 标准下的年份和星期编号。
  • time.YearDay():获取时间点 time 对应的那一年的第几天,平年的返回值范围 [1,365] ,闰年 [1,366] 。
  • time.Weekday():获取时间点 time 对应的那一周的周几。
  • time.Hour():获取时间点 time 对应的那一天的第几小时,范围 [0, 23] 。
  • time.Minute():获取时间点 time 对应的那一小时的第几分钟,范围 [0, 59] 。
  • time.Second():获取时间点 time 对应的那一分钟的第几秒,范围 [0, 59] 。
  • time.Nanosecond():获取时间点 time 对应的那一秒内的纳秒偏移量,范围 [0, 999999999] 。
  • time.Unix():Unix 将 time 表示为 Unix 时间,即从时间点 January 1, 1970 UTC 到时间点 time 所经过的时间(单位秒)。
  • time.UnixNano():将 time 表示为 Unix 时间,即从时间点 January 1, 1970 UTC 到时间点 time 所经过的时间(单位纳秒)。如果纳秒为单位的 Unix 时间超出了 int64 能表示的范围,结果是未定义的。注意这就意味着 Time 零值调用 UnixNano 方法的话,结果是未定义的。

下面是一个例子:

package main

import (
 "fmt"
 "time"
)

func main() {
 t := time.Now()
 fmt.Println(t)
 // 2022-03-03 23:40:26.1478777 +0800 CST m=+0.013198301
 fmt.Println(t.Date()) // 2022 March 3
 fmt.Println(t.Clock()) // 23 40 26
 fmt.Println(t.Year()) // 2022
 fmt.Println(t.Month()) // March
 fmt.Println(t.Day()) // 3
 fmt.Println(t.ISOWeek())// 2022 9
 fmt.Println(t.YearDay())// 62
 fmt.Println(t.Weekday())// Thursday
 fmt.Println(t.Hour()) // 23
 fmt.Println(t.Minute()) // 40
 fmt.Println(t.Second()) // 26
 fmt.Println(t.Nanosecond()) // 147877700
 fmt.Println(t.Unix()) // 1646322026
 fmt.Println(t.UnixNano()) // 1646322026147877700
}


Duration 类型

Duration 类型代表两个时间点之间经过的时间,以纳秒为单位。可表示的最长时间段大约 290 年:

type Duration int64

time 包中定义的时间常量:

const (
 Nanosecond  Duration = 1 // 纳秒
 Microsecond          = 1000 * Nanosecond // 微秒
 Millisecond          = 1000 * Microsecond // 毫秒
 Second               = 1000 * Millisecond // 秒
 Minute               = 60 * Second // 分钟
 Hour                 = 60 * Minute // 小时
)


time.Date()

使用 time.Date() 方法能返回一个特定时区的时间点:

func Date(year int, month Month, day, hour, min, sec, nsec int, loc *Location) Time {...}

month、day、hour、min、sec和nsec的值可能会超出它们的正常范围,在转换前函数会自动将之规范化。如果 loc 为 nil 会 panic 。下面是一个例子:

package main

import (
 "fmt"
 "time"
)

func main() {
 t := time.Date(2022, time.March, 32210300, time.UTC)
 fmt.Println(t)
}

运行后会输出:

2022-03-03 22:10:30 +0000 UTC


时间运算相关方法

  • time.Equal(u Time):判断两个时间是否相同,会考虑时区的影响,因此不同时区标准的时间也可以正确比较。本方法会比较地点和时区信息。
  • time.Before(u Time):如果时间点 time 在 u 之前,返回真;否则返回假。
  • time.After(u Time):如果时间点 time 在 u 之后,返回真;否则返回假。
  • time.Add(d Duration):返回时间点 time+d。
  • time.AddDate(years int, months int, days int):返回增加了给出的年份、月份和天数的时间点 Time。
  • time.Sub(u Time):返回一个时间段 time-u。

下面是一个例子:

package main

import (
 "fmt"
 "time"
)

func main() {

 t1 := time.Date(20223323000, time.UTC)
 t2 := time.Date(20223323000, time.UTC)
 t3 := time.Date(2022345670, time.UTC)

 fmt.Printf("t1 equal t2? %v\n", t1.Equal(t2)) // t1 equal t2? true
 fmt.Printf("t1 equal t3? %v\n", t1.Equal(t3)) // t1 equal t3? false

 fmt.Printf("t1 before t2? %v\n", t1.Before(t2)) // t1 before t2? false
 fmt.Printf("t1 before t3? %v\n", t1.Before(t3)) // t1 before t3? true

 fmt.Printf("t1 after t2? %v\n", t1.After(t2)) // t1 after t2? false
 fmt.Printf("t3 after t1? %v\n", t3.After(t1)) // t3 after t1? true

 t := time.Now()
 fmt.Println(t) // 2022-03-03 23:42:04.1729043 +0800 CST m=+0.013102601
 fmt.Println(t.Add(1000000000)) // 2022-03-03 23:42:05.1729043 +0800 CST m=+1.013102601

 fmt.Println(t) // 2022-03-03 23:42:04.1729043 +0800 CST m=+0.013102601
 fmt.Println(t.AddDate(123)) // 2023-05-06 23:42:04.1729043 +0800 CST

 fmt.Println(t3.Sub(t1)) // 6h6m7s
}


日期格式化

我们可以使用 Printf() 或者 SPrintf() 对日期进行格式化,也可以使用 time.Format() 方法完成日期的格式化。下面是一个例子:

package main

import (
 "fmt"
 "time"
)

func main() {
 t := time.Now()
 fmt.Printf("当前时间:%d年%d月%d日 %d时%d分%d秒\n",
  t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute(), t.Minute())
  // 当前时间:2022年3月3日 23时49分49秒

 dataStr := fmt.Sprintf("当前时间:%d年%d月%d日 %d时%d分%d秒\n",
  t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute(), t.Minute())

 fmt.Printf("dataStr = %v", dataStr)
 // dataStr = 当前时间:2022年3月3日 23时49分49秒

 fmt.Printf(t.Format("2006-01-02 15:04:05"))
 // 2022-03-03 23:49:26
 fmt.Println()
 fmt.Printf(t.Format("15:04:05"))
 // 23:49:26
}

注意:上面格式化日期代码中的日期必须是 2006年1月2日15时4分5秒

👇希望对你有帮助,期待你的关注👇

    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多