目录
一、介绍简单的几个时间UTC、CST、CDT
1、UTC 代表 世界协调时间(Universal Time Coordinated,UTC),也就是零时区的时间(格林威治时间)。
2、UTC和 中国的时间
- 当UTC时间是2022年10月8日星期六13:00时,中国时间是21:00。
- UTC 比 中国 慢 8 小时.
3、CST中部标准时间(Central Standard Time) 可以为下面4个不同的时区的缩写:
- 中国标准时间:China Standard Time,UTC + 8:00
- 澳大利亚中部时间:Central Standard Time (Australia),UTC + 9:30
- 古巴标准时间:Cuba Standard Time,UTC - 4:00
- 美国中部时间:Central Standard Time (USA),UTC - 6:00
4、CDT表示中部夏令时间(Central Daylight Time),比世界协调时间(UTC)晚05:00小时。该时区为夏令时时区,主要用于 北美
中部夏令时间(CDT)=UTC- 05:00
二、获取时间的函数
1、通过调用time包中的一些函数即可获得当前时间
func time() {
now := time.Now() // 输出now可获取当前北京时间
year := now.Year() // 年
month := now.Month() // 月
day := now.Day() // 日
hour := now.Hour() // 小时
minute := now.Minute() // 分钟
second := now.Second() // 秒
}
三、时间的加、减、等
1、Add函数可求未来时间,即该函数返回的是时间
func (t Time) Add(d Duration) Time
func main() {
now := time.Now()//获取当前时间
after:= now.Add(time.Hour) // 当前时间加1小时后的时间,now是现在时间,time.Hour指一个小时
fmt.Println(after)//输出一个小时之后的时间
}
2、Sub函数可求 二者时间之差,调用方法和Add一致,返回的是一段时间
func (t Time) Sub(u Time) Duration
3、Equal函数判断两个时间是否相同,返回是bool值,调用方法也是和Add和Sub一样的
func (t Time) Equal(u Time) bool
四、判断两时间发生前后
1、Before函数判断t时间是否早于参数u时间,如果早就放回true,否则返回false;
func (t Time) Before(u Time) bool
2、After函数判断t时间是否晚于于参数u时间,如果早就放回true,否则返回false;
func (t Time) After(u Time) bool
五、周期性定时器 time.Tick(时间间隔)
1、该函数用来设置周期性定时器的,它实际上是一个channel(不同goroutine间用来传递信息的东东),参数中每隔五秒就传一个时间过去给i,for循环中的i接收通道中的值后,通道就没有值了,直到五秒后time.Tick()传数值给timer这个通道后i才有值。因此使得五秒输出一次时间。
func timer() {
timer:= time.Tick(time.Second*5) //定义一个5秒间隔的周期性定时器
fmt.Println(timer)//输出的仅仅只是一个十六进制位的地址,0xc00005e060
for i := range timer{
fmt.Println(i) //每隔五秒输出一次时间
}
}
输出如下:
2022-10-08 21:03:03.6887817 +0800 CST m=+5.012945701
2022-10-08 21:03:08.6868233 +0800 CST m=+10.010987301
2022-10-08 21:03:13.6821592 +0800 CST m=+15.006323201
2022-10-08 21:03:18.6839857 +0800 CST m=+20.008149701
一次性定时器time.NewTimer(参数时间)的内容不做过多介绍:下面是使用它时常用的函数
func(t *Timer) Stop() bool
func (t *Timer) Reset(d Duration) bool
六、时间也有格式化
time.Format()函数能够将一个时间对象格式化输出为指定布局的文本表示形式。(括号里填的就是你想要格式化成为的类型)
func formatDemo() {
now := time.Now()
// 格式化的模板为 2006-01-02 15:04:05
// 24小时制
fmt.Println("24小时制:")
fmt.Println("2006-01-02 15:04:05.000 Mon Jan") //2006-01-02 15:04:05.000 Mon Jan
fmt.Println(now.Format("2006-01-02 15:04:05.000 Mon Jan"))//2022-10-08 22:43:45.173 Sat Oct
}
需要注意的是 Go 语言中时间格式化的布局不是常见的Year-Month-Day Hour:Minute:Second
,而是使用 2006-01-02 15:04:05.000
(记忆口诀为2006 1 2 3 4 5),只能使用这个固定的时间来格式化
- 如果想格式化为12小时格式,需在格式化布局中添加
PM
。 - 小数部分想保留指定位数就写0,如果想省略末尾可能的0就写 9。
func formatDemo() {
now := time.Now()
// 格式化的模板为 2006-01-02 15:04:05
// 12小时制
fmt.Println("12小时制:")
fmt.Println("2006-01-02 15:04:05.000 Mon Jan")
fmt.Println(now.Format("2006-01-02 03:04:05.000 PM Mon Jan"))//2022-10-08 22:43:45.173 Sat Oct
// 小数点后写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")) //22:43:45
// 只格式化日期部分
fmt.Println(now.Format("2006.01.02"))//2022.10.08
}
时间换算:
1s【秒】 = 1000ms【毫秒】
1ms【毫秒】 = 1000μs【微秒】
1μs【微秒】 = 1000ns【纳秒】
七、时间字符串格式的解析
1、time.Parse(layout,value string)函数在解析时不需要额外指定时区信息,其中layout参数是固定的
func Parse(layout, value string) (Time, error)
layout
的时间必须是"2006-01-02 15:04:05"
这个时间,不管格式如何变,时间点不变就行,一变就出错。
func parse() {
// 在没有时区指示符的情况下,time.Parse 返回UTC时间
timeObj, err := time.Parse("2006/01/02 15:04:05", "2022/10/08 21:30:20")
if err != nil {
fmt.Println(err)
return
}
fmt.Println(timeObj) // 2022-10-08 21:30:20 +0000 UTC
// 在有时区指示符的情况下,time.Parse 返回对应时区的时间表示
// RFC3339 = "2006-01-02T15:04:05Z07:00"
timeObj, err = time.Parse(time.RFC3339, "2022-10-08T21:30:20+08:00")
if err != nil {
fmt.Println(err)
return
}
fmt.Println(timeObj) // 2022-10-05 11:25:20 +0800 CST
}
2、time.ParseInLocation(
layout string, value string, loc *Location)
函数需要在解析时额外指定时区信息
func parseLocation() {
now := time.Now()
fmt.Println(now)//输出现在时间
// 加载时区
loc, err := time.LoadLocation("Asia/Shanghai")
if err != nil {
fmt.Println(err)
return
}
fmt.Println(loc)//Asia/Shanghai
// 按照指定时区和指定格式解析字符串时间
timeObj, err := time.ParseInLocation("2006/01/02 15:04:05", "2022/10/08 12:00:00", loc)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(timeObj)
fmt.Println(timeObj.Sub(now))
}
八、时区(time zone)
go语言用time.FixedZone和
time.LoadLocation这两个函数则是用来获取location信息。
1、time.FixedZone()
func FixedZone(name string, offset int) *Location
func timezoneDemo() {
now1 := time.Hour
fmt.Println(now1) //1h0m0s
fmt.Println(now1.Seconds()) //3600(转为秒)
secondsEastOfUTC := (8 * time.Hour).Seconds()//即将八个小时转为秒
fmt.Printf("%T \n", secondsEastOfUTC) //float64
fmt.Println(secondsEastOfUTC) //28800(这时为浮点型)
secondsEastOfUTC1 := int((8 * time.Hour).Seconds()) //将浮点型强转为整型
fmt.Printf("八小时的秒数=8*60*60=%d\n", secondsEastOfUTC1) //八小时的秒数=8*60*60=28800
//FixedZone 返回始终使用给定区域名称和偏移量(UTC 以东秒)的 Location。
beijing := time.FixedZone("Beijing Time", secondsEastOfUTC1) //此时创建了一个名为Beijing的UTC+08:00时区
fmt.Printf("%T\n", beijing) //*time.Location
fmt.Println(beijing)
// 因为使用 time.FixedZone()创建了一个时区,所以如果当前系统有时区数据库,则可以使用time.LoadLocation()这个函数加载Beijing这个位置得到对应的时区
}
2、time.LoadLocation()
以下是这个加载时区函数time.LoadLocation()的用例
func timezoneDemo() {
beijing := time.FixedZone("Beijing Time", 28800)//此时创建了一个名为Beijing的UTC+08:00时区
newYork, err := time.LoadLocation("America/New_York") // UTC-05:00
if err != nil {
fmt.Println("load America/New_York location failed", err)
return
}
// 创建时间对象需要指定位置。常用的位置是 time.Local(当地时间) 和 time.UTC(UTC时间)。
//timeInLocal := time.Date(2009, 1, 1, 20, 0, 0, 0, time.Local) // 系统本地时间
timeInUTC := time.Date(2009, 1, 1, 12, 0, 0, 0, time.UTC)
sameTimeInBeijing := time.Date(2009, 1, 1, 20, 0, 0, 0, beijing)
sameTimeInNewYork := time.Date(2009, 1, 1, 7, 0, 0, 0, newYork)
// 北京时间(东八区)比UTC早8小时,所以上面两个时间看似差了8小时,但表示的是同一个时间
timesAreEqual := timeInUTC.Equal(sameTimeInBeijing)
fmt.Println(timesAreEqual)//true
// 纽约(西五区)比UTC晚5小时,所以上面两个时间看似差了5小时,但表示的是同一个时间
timesAreEqual = timeInUTC.Equal(sameTimeInNewYork)
fmt.Println(timesAreEqual)//true
}
九、Unix Time
Unix Time是自1970年1月1日 00:00:00 UTC 至当前时间所经过的总秒数。
在go语⾔中,
时间戳就是【北京时间1970年01⽉01⽇08时00分00秒】到【北京时间此时此刻】的总秒数。
或者是【格林威治时间1970年01⽉01⽇00时00分00秒】到【格林威治时间此时此刻】的总秒数。
因此上⾯得到的⼏个时间戳是⼀样的
func timeUnix() {
now := time.Now() // 获取当前时间
timestamp := now.Unix() // 秒级时间戳
milli := now.UnixMilli() // 毫秒时间戳 Go1.17+
micro := now.UnixMicro() // 微秒时间戳 Go1.17+
nano := now.UnixNano() // 纳秒时间戳
fmt.Println(timestamp, milli, micro, nano)//1665244324 1665244324157 1665244324157847 1665244324157847400
}