前言
本文主要介绍使用标准库中的time包
进行时间处理。快速掌握时区设置、时间戳获取,以及时间格式化等操作。
时区设置
1. 默认使用本地时区
本地指的是程序运行所属环境(物理机或容器等)。例如本地设置的是北京时间(Asia/Shanghai
),则获取到的时间就是东八区的时间
func main() {
fmt.Println(time.Now())
fmt.Println(time.Now().Location())
}
输出:
2023-02-19 22:52:38.217136 +0800 CST m=+0.000072078
Local
2.使用os.Setenv()设置时区
使用os包设置环境变量TZ为对应时区。注意:1.该设置一定要在time包使用之前,否则无效;2.依赖当前系统的时区数据库,有则可以加载一个位置得到对应的时区,无则兜底使用UTC
func main() {
os.Setenv("TZ", "Asia/Shanghai")
fmt.Println(time.Now())
fmt.Println(time.Now().Location())
}
输出:
2023-02-19 22:54:05.885626 +0800 CST m=+0.000077761
Asia/Shanghai
3.使用time.LoadLocation()设置时区
依赖当前系统的时区数据库,有则可以加载一个位置得到对应的时区,无则会返回一个error
func main() {
loc, err := time.LoadLocation("Asia/Shanghai")
if err != nil {
fmt.Println("LoadLocation error: " + err.Error())
return
}
fmt.Println(time.Now().In(loc))
fmt.Println(time.Now().In(loc).Location())
}
正确输出:
2023-02-19 23:03:22.543069 +0800 CST
Asia/Shanghai
错误输出:LoadLocation error: unknown time zone Asia/ShanghaiA
4.使用内置的time.UTC和time.Local快速切换时区
time.UTC
设置为UTC;time.Local
设置为本地默认时区
func main() {
fmt.Println(time.Now().In(time.UTC))
fmt.Println(time.Now().In(time.UTC).Location())
fmt.Println(time.Now().In(time.Local))
fmt.Println(time.Now().In(time.Local).Location())
}
输出:
2023-02-19 15:22:41.626207 +0000 UTC
UTC
2023-02-19 23:22:41.626254 +0800 CST
Local
获取当前时间信息
通过time.Now
获取当前的时间对象,然后从时间对象中可以获取到年、月、日、时、分、秒等信息
func main() {
t := time.Now() // 获取当前时间
fmt.Printf("当前时间:%v\n", t)
year := t.Year() // 年
month := t.Month() // 月
day := t.Day() // 日
hour := t.Hour() // 小时
minute := t.Minute() // 分钟
second := t.Second() // 秒
fmt.Println(year, month, day, hour, minute, second)
}
输出:
当前时间:2023-02-19 23:36:46.75675 +0800 CST m=+0.000270495
2023 February 19 23 36 46
获取时间戳
1.当前时间的时间戳
通过time.Now
获取当前的时间对象,然后使用时间对象调用相关方法获取时间戳。
注意:毫秒和微秒的方法,在Go1.17之后才能使用,之前的版本可以通过纳秒进行计算转换
func main() {
t := time.Now()
sec := t.Unix() //秒
mill := t.UnixNano() / 1e6 //毫秒
//mill := t.UnixMilli() //毫秒,要求Go1.17+
micro := t.UnixNano() / 1e3 //微秒
//micro := t.UnixMicro() //微秒,要求Go1.17+
nano := t.UnixNano() //纳秒
fmt.Println(sec, mill, micro, nano)
}
输出:
1676821481 1676821481283 1676821481283263 1676821481283263000
2.指定时间的时间戳
使用time.ParseInLocation
指定时区解析指定时间,并获取到时间对象,然后调用相关方法获取时间戳
func main() {
t, err := time.ParseInLocation("2006-01-02 15:04:05", "2023-02-19 21:00:00", time.Local)
if err != nil {
fmt.Println("ParseInLocation error:" + err.Error())
}
fmt.Println(t)
sec := t.Unix() //秒
mill := t.UnixNano() / 1e6 //毫秒
micro := t.UnixNano() / 1e3 //微秒
nano := t.UnixNano() //纳秒
fmt.Println(sec, mill, micro, nano)
}
输出:
2023-02-19 21:00:00 +0800 CST
1676811600 1676811600000 1676811600000000 1676811600000000000
时间格式化
Go语言的格式化布局规则,比较特殊,不是使用常规的“Y-m-d H:M:S”,而是使用“2006-01-02 15:04:05.000”
含义说明:
- 2006:年(Y)
- 01:月(m)
- 02:日(d)
- 15:时(H)。若想表示12小时制则写为03,并且后面加上PM
- 04:分(M)
- 05:秒(S)
- 特殊:小数部分想保留指定位数就写0,如果想省略末尾可能的0就写 9
使用示例:
func main() {
t := time.Now()
//24小时制
fmt.Println(t.Format("2006-01-02 15:04:05"))
//12小时制(时占位03并且后面加上PM)
fmt.Println(t.Format("2006-01-02 03:04:05 PM"))
//小数点0或9
fmt.Println(t.Format("2006-01-02 15:04:05.000"))
fmt.Println(t.Format("2006-01-02 15:04:05.999"))
//只要日期
fmt.Println(t.Format("2006-01-02"))
//只要时间
fmt.Println(t.Format("15:04:05"))
}
输出:
2023-02-20 00:48:12
2023-02-20 12:48:12 AM
2023-02-20 00:48:12.223
2023-02-20 00:48:12.223
2023-02-20
00:48:12
时间间隔
time.Duration
代表两个时间点之间经过的时间,以纳秒为单位。可表示的最长时间段大约290年
time 包定义的时间间隔常量:
const (
Nanosecond Duration = 1
Microsecond = 1000 * Nanosecond
Millisecond = 1000 * Microsecond
Second = 1000 * Millisecond
Minute = 60 * Second
Hour = 60 * Minute
)
常用方法:
- Add:func (t Time) Add(d Duration) Time,指定时间间隔(t+d),得到一个新的时间对象
- Sub:func (t Time) Sub(u Time) Duration,求两个时间之间的差值(t-d)
使用示例:
func main() {
t := time.Now()
t2 := t.Add(1 * time.Hour) //一个小时之后的时间
t3 := t.Add(-1 * time.Hour) //一个小时之前的时间
fmt.Println(t) //2023-02-20 01:18:00.204169 +0800 CST m=+0.000410087
fmt.Println(t2) //2023-02-20 02:18:00.204169 +0800 CST m=+3600.000410087
fmt.Println(t3) //2023-02-20 00:18:00.204169 +0800 CST m=-3599.999589913
time.Sleep(2 * time.Second)
fmt.Println(t.Sub(time.Now())) //-2.005207034s
fmt.Println(time.Now().Sub(t)) //2.00532078s
}
定时器
使用time.Tick(时间间隔)
来设置定时器,定时器的本质上是一个通道(channel)。可用于处理定时执行的任务
func timeTick() {
ticker := time.Tick(time.Second) //定义一个1秒间隔的定时器
for i := range ticker {
fmt.Println(i) //每秒都会执行的任务
}
}
输出:
2023-02-20 01:25:18.310543 +0800 CST m=+3.010979096
2023-02-20 01:25:19.31052 +0800 CST m=+4.010955881
2023-02-20 01:25:20.31051 +0800 CST m=+5.010945974
总结
对时区设置、时间戳获取,以及时间格式化等操作,做了详细的讲解。记住所有的操作,都得基于时间对象,来展开的,时间对象是时间处理的基石。
如果本文对你有帮助,欢迎点赞收藏加关注,如果本文有错误的地方,欢迎指出!
本文参与了SegmentFault 思否写作挑战赛,欢迎正在阅读的你也加入。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。