咱们好,我是煎鱼

Go 言语中有一个东西是比较有特色的,那就是 time 规范库,在各类与时刻有关的场景都会常常用到,例如:守时/推迟任务、数据更新、时刻比较。

官方 Demo 是一个计算时刻差的样例:

import "time"
func main() {
	start := time.Now()
	time.Sleep(time.Second)
	t := time.Now()
	elapsed := t.Sub(start)
	println(elapsed)
}

输出成果:

1000000000

神秘的 2006-01-02 15:04:05

在社区反应中,更虎的是以下这个样例:

func main() {
	now := time.Now()
	v := now.Format("2006-01-02 15:04:05")
	println(v)
}

输出成果:

2009-11-10 23:00:00

这时候咱们会遇到几个问题…最被常问的是 2006-01-02 15:04:05,这是随意写的时刻点吗,甚至还曾经有传言说这是 Go 言语的诞生时刻…

为什么是这个时刻点

实际上 2006-01-02 15:04:05 是一个参阅时刻的格局,也就是其它言语中 Y-m-d H:i:s 格局,在功能上用于时刻的格局化处理和规范。

那为什么是 2006-01-02 15:04:05 呢?其实这些 ”数字“ 是有意义的,每个布局字符串都是一个时刻戳的表示,并非随意写的时刻点。

可参见官方例子中的如下办法:

Jan 2 15:04:05 2006 MST
1   2  3  4  5    6  -7

咱们也可以将其回忆为 2006 年 1 月 2 日 3 点 4 分 5 秒。

确实背不下来,快优化

虽然 Go 官方给出了一系列感觉很合理的解说,也经过上面的办法试图教会咱们靠了解而不是靠纯背把这个时刻点格局规范给记下来…

现实是很严酷的,母语不同,事务类型不同,不会常常用到 time 规范库,很容易忘掉详细数值。

大佬也分析了 Go modules 上的一切模块代码,发现这个日期时刻点,运用的次数十分高频:

排名 频率 格局
1 75616 time.RFC3339
2 23954 time.RFC3339Nano
3 13312 “2006-01-02 15:04:05”
4 12332 “2006-01-02”
5 11940 time.RFC1123

综上数据所述,终于在 Go 过去了 13 年后,将会在 Go1.20 增加如下三个常量:

DateTime   = "2006-01-02 15:04:05"
DateOnly   = "2006-01-02"
TimeOnly   = "15:04:05"

新版别中直接引证即可。

今后问这是什么意思的同学,可能会变少。

支撑比较:Time.Compare

目前在规范库中,有 3 个办法来比较 time.Time 目标,分别是:Before()、Equal() 和 After(),作用上相似 <、== 和 >。但缺少 <= 和 >= 的等价物,因此在程序中实施起来会比较麻烦。

常常一番评论,将会在 Go1.20 支撑 Time.Compare,以此来达到相似的作用。作用是将 Time 目标 t 和 u 两者进行比较。

函数回来如下几种成果:

  • 假如 t 在 u 之前,则回来 -1。
  • 假如 t 在 u 之后,则回来 +1。
  • 假如它们相同,则回来 0。

源代码如下:

func (t Time) Compare(u Time) int {
	var tc, uc int64
	if t.wall&u.wall&hasMonotonic != 0 {
		tc, uc = t.ext, u.ext
	} else {
		tc, uc = t.sec(), u.sec()
		if tc == uc {
			tc, uc = int64(t.nsec()), int64(u.nsec())
		}
	}
	switch {
	case tc < uc:
		return -1
	case tc > uc:
		return +1
	}
	return 0
}

函数内部比较简单。

总结

Go Time 一直都是论题榜上的老面孔。这一次在 Go1.20 的新特性中,对 2006-01-02 15:04:05 常用的时刻点进行了常量声明,便于咱们后续直接引证,不必 “死记硬背”。

在 Time 目标的比较上,也补全了 Compare 办法,便于两个时刻目标之前之后的比照。

Go1.20 将在下一年 2023 年 2,3 月份左右就可以见到了。11 月底会发预览版别。冲不?

文章继续更新,可以微信搜【脑子进煎鱼了】阅读,本文 GitHub github.com/eddycjy/blo… 已录入,学习 Go 言语可以看 Go 学习地图和路线,欢迎 Star 催更。

Go 图书系列

  • Go 言语入门系列:初探 Go 项目实战
  • Go 言语编程之旅:深化用 Go 做项目
  • Go 言语规划哲学:了解 Go 的为什么和规划考虑
  • Go 言语进阶之旅:进一步深化 Go 源码

引荐阅读

  • Go for 循环有时候真的很坑。。。
  • Go 十年了,终于想起要一致 log 库了!
  • Go 只会 if err != nil?这是不对的,分享这些高雅的处理姿势给你!