首页 > 编程笔记 > Go语言笔记 阅读:9

G语言表示时间日期的3种方法(附带实例)

日期和时间是编程语言中常用的功能之一,如果没有日期和时间,就会导致许多功能无法实现,比如日志记录、定时任务、等待延时等。

在 Go语言中,日期与时间可以分为 3 种表示方式,分别是时间戳、结构体 Time 和字符串格式化,三者之间的数据类型能相互转换。

Go语言时间戳

时间戳是指格林尼治时间 1970 年 1 月 1 日 00 时 00 分 00 秒,即北京时间 1970 年 1 月 1 日 08 时 00 分 00 秒至现在的总秒数。

Go语言的内置包 time 提供结构体方法 Unix() 和 UnixNano() 生成秒级时间戳和纳秒级时间戳,示例如下:
package main

import (
   "fmt"
   "time"
)

func main() {
   // 获取当前时间
   now := time.Now()
   // 生成秒级时间戳
   t1 := now.Unix()
   // 生成纳秒级时间戳
   t2 := now.UnixNano()
   fmt.Printf("现在的秒级时间戳:%v,类型:%T\n", t1, t1)
   fmt.Printf("现在的纳秒级时间戳:%v,类型:%T\n", t2, t2)
}
运行上述代码,结果为:
现在的秒级时间戳:1706183096,类型:int64
现在的纳秒级时间戳:1706183096000000000,类型:int64
上述例子的代码说明如下:
1)由内置包 time 调用工厂函数 Now() 生成结构体 Time 实例化对象,工厂函数 Now() 以当前时间为准,结构体 Time 设有 3 个结构体成员:wall、ext 和 loc,如下图所示。


图 1 结构体Time

2)由结构体 Time 实例化对象分别调用结构体方法 Unix() 和 UnixNano() 生成秒级时间戳和纳秒级时间戳,时间戳皆以整型类型表示。

Go语言结构体Time

结构体 Time 是 Go语言对时间的具体表现,它将时间以结构体 Time 表示,由结构体实例化对象调用结构体方法或结构体成员获取时间信息,示例如下:
package main

import (
   "fmt"
   "time"
)

func main() {
   // 获取当前时间
   now := time.Now()
   fmt.Printf("当前时间:%v\n", now)
   // 获取当前时间的年
   year := now.Year()
   fmt.Printf("获取当前时间的年:%v\n", year)
   // 获取当前时间的月
   month := now.Month()
   fmt.Printf("获取当前时间的月,英文格式:%v\n", month)
   fmt.Printf("获取当前时间的月,数字格式:%v\n", int(month))
   // 获取当前时间的日
   day := now.Day()
   fmt.Printf("获取当前时间的日:%v\n", day)
   // 获取当前时间的小时
   hour := now.Hour()
   fmt.Printf("获取当前时间的小时:%v\n", hour)
   // 获取当前时间的分钟
   minute := now.Minute()
   fmt.Printf("获取当前时间的分钟:%v\n", minute)
   // 获取当前时间的秒
   second := now.Second()
   fmt.Printf("获取当前时间的秒:%v\n", second)
   // 获取当天是星期几
   wk := now.Weekday()
   fmt.Printf("获取当天是星期几:%v\n", wk)
}
运行上述代码,结果为:
当前时间:2024-03-26 15:42:31.123456789 +0800 CST
获取当前时间的年:2024
获取当前时间的月,英文格式:March
获取当前时间的月,数字格式:3
获取当前时间的日:26
获取当前时间的小时:15
获取当前时间的分钟:42
获取当前时间的秒:31
获取当天是星期几:Tuesday
上述例子的代码说明如下:
1) 使用内置包 time 调用工厂函数 Now(),根据当前时间创建结构体 Time 实例化对象。

2) 由结构体 Time 实例化对象调用结构体方法 Year()、Month()、Day()、Hour()、Minute()、Second() 分别获取当前时间的年份、月份(月份包含英文格式和数字格式)、天数、小时、分钟和秒数。

除此之外,结构体 Time 还定义了许多结构体方法,我们可以在 GoLand 的语法提示中查看,以当前时间 now := time.Now() 为例,如下图所示。


图 2 语法提示

Go语言字符串格式化

时间的字符串格式化是将时间以字符串格式表示,它将结构体 Time 实例化对象转化为字符串,示例如下:
package main

import (
   "fmt"
   "time"
)

func main() {
   // 获取当前时间
   now := time.Now()
   // 字符串格式化的模板为Go的出生时间2006年1月2日15点04分 Mon Jan
   // 24小时制
   t1 := now.Format("2006-01-02 15:04:05.000 Mon Jan")
   fmt.Printf("24小时制:%v\n", t1)
   // 12小时制
   t2 := now.Format("2006-01-02 03:04:05.000 PM Mon Jan")
   fmt.Printf("12小时制:%v\n", t2)
   // 时间显示格式为:年/月/日 时:分
   t3 := now.Format("2006/01/02 15:04")
   fmt.Printf("时间显示格式为:年/月/日 时:分:%v\n", t3)
   // 时间显示格式为:时:分 年/月/日
   t4 := now.Format("15:04 2006/01/02")
   fmt.Printf("时间显示格式为:时:分 年/月/日:%v\n", t4)
   // 时间显示格式为:年/月/日
   t5 := now.Format("2006/01/02")
   fmt.Printf("时间显示格式为:年/月/日:%v\n", t5)
   // 时间显示格式为:年-月-日
   t6 := now.Format("2006-01-02")
   fmt.Printf("时间显示格式为:年-月-日:%v\n", t6)
   // 时间显示格式为:日-月-年
   t7 := now.Format("02-01-2006")
   fmt.Printf("时间显示格式为:日-月-年:%v\n", t7)
   // 时间显示格式为:时:分:秒
   t8 := now.Format("15:04:05.000")
   fmt.Printf("时间显示格式为:时:分:秒:%v\n", t8)
   // 时间显示格式为:时-分-秒
   t9 := now.Format("15-04-05.000")
   fmt.Printf("时间显示格式为:时-分-秒:%v\n", t9)
}
运行上述代码,结果为:
24小时制:2024-03-26 15:42:31.123456789 Monday Mar
12小时制:2024-03-26 03:42:31.123456789 PM Mar
时间显示格式为:年/月/日 时:分:2024/03/26 15:42
时间显示格式为:时:分 年/月/日:15:42 2024/03/26
时间显示格式为:年/月/日:2024/03/26
时间显示格式为:年-月-日:2024-03-26
时间显示格式为:日-月-年:26-03-2024
时间显示格式为:时:分:秒:15:42:31.123456789
时间显示格式为:时-分-秒:15-42-31.123456789
上述示例是将当前时间转为字符串格式,转换过程由结构体方法 Format() 实现,实现过程如下:

Go语言时间类型的相互转换

Go语言的时间类型分为时间戳、结构体 Time 和字符串格式化,三者之间能通过特定方法实现相互转换,具体的转换过程如下:
package main

import (
   "fmt"
   "time"
)

func main() {
   /* 时间戳 */
   var timestamp int64 = 1630315335
   // 时间戳转换为结构体Time
   tm := time.Unix(timestamp, 0)
   fmt.Printf("时间戳转换结构体Time:%v\n", tm)
   // 时间戳转换为字符串格式化
   tms := time.Unix(timestamp, 0).Format("2006-01-02 15:04:05")
   fmt.Printf("时间戳转换字符串格式化:%v\n", tms)

   /* 结构体Time */
   now := time.Now()
   // 结构体Time转换为时间戳
   // 生成秒级时间戳
   fmt.Printf("结构体Time转换秒级时间戳:%v\n", now.Unix())
   // 生成纳秒级时间戳
   fmt.Printf("结构体Time转换纳秒级时间戳:%v\n", now.UnixNano())
   // 结构体Time转换为字符串格式化
   tms1 := now.Format("2006-01-02 15:04:05")
   fmt.Printf("结构体Time转换字符串格式化:%v\n", tms1)

   /* 字符串格式化 */
   layout := "2006-01-02 15:04:05"
   timeStr := "2021-08-30 17:34:05.1099536"
   // 字符串格式化转换为结构体Time
   // 函数Parse()用于转换UTC时间格式
   timeObj, _ := time.Parse(layout, timeStr)
   fmt.Printf("字符串格式化转换结构体Time:%v\n", timeObj)
   // 字符串格式化转换为结构体Time
   // 函数ParseInLocation()用于转换当地时间格式
   timeObj1, _ := time.ParseInLocation(layout, timeStr, time.Local)
   fmt.Printf("字符串格式化转换结构体Time:%v\n", timeObj1)
   // 字符串格式化转换为时间戳
   // 先转换为结构体Time,再由结构体Time转换为时间戳
   timeObj2, _ := time.ParseInLocation(layout, timeStr, time.Local)
   // 转换时间戳
   t1 := timeObj2.Unix()
   fmt.Printf("字符串格式化转换秒级时间戳:%v\n", t1)
   t2 := timeObj2.UnixNano()
   fmt.Printf("字符串格式化转换纳秒级时间戳:%v\n", t2)
}
运行上述代码,结果为:
时间戳转换结构体Time:2021-08-30 17:22:15 +0800 CST
时间戳转换字符串格式化:2021-08-30 17:22:15
结构体Time转换秒级时间戳:1630374540
结构体Time转换纳秒级时间戳:1630374540235721900
结构体Time转换字符串格式化:2021-08-31 09:49:00
字符串格式化转换结构体Time:2021-08-30 17:34:05.1099536 +0000 UTC
字符串格式化转换结构体Time:2021-08-30 17:34:05.1099536 +0800 CST
字符串格式化转换秒级时间戳:1630316045
字符串格式化转换纳秒级时间戳:1630316045109953600
上述代码分别演示了时间戳、结构体 Time 和字符串格式化的相互转换过程,具体说明如下:
1) 时间戳转换为结构体 Time 和字符串格式化必须先转换为结构体 Time,再从结构体 Time 转换为字符串格式化。

调用内置包 time 的函数 Unix() 将整型转换为结构体 Time,生成结构体实例化对象,再调用结构体方法 Format() 生成字符串格式化。

2) 结构体 Time 转换为时间戳和字符串格式化必须由结构体实例化对象分别调用结构体方法 Unix()、UnixNano() 和 Format()。Unix() 和 UnixNano() 分别转换为秒级时间戳和纳秒级时间戳,Format() 是转换为字符串格式化。

3) 字符串格式化分别转换为时间戳和结构体 Time 必须先转换为结构体 Time,再从结构体 Time 转换为时间戳。

调用内置包 time 的函数 Parse() 和 ParseInLocation() 分别将字符串格式化转换为结构体 Time,函数 Parse() 是转换为 UTC 时间格式,函数 ParseInLocation() 是转换为当地时间格式,再由结构体 Time 调用结构体方法 Unix()、UnixNano() 生成时间戳。

综上所述,时间戳、结构体 Time 和字符串格式化的相互转换必须以结构体 Time 为中心,比如时间戳转换为字符串格式化,必须将时间戳转换为结构体 Time,再由结构体 Time 转换为字符串格式化,反之亦然。

相关文章