Go语言标准库之time使用介绍,让你了解什么是UTC、GMT、Unix时间戳、CST、CET、DST时间

Go语言的time库中包含了对时间进行管理的所有操作,本文介绍一下time库的使用,后续持续更新。

1. 时间的类型

Go语言的time库采用公历的方式记录日期,我们可以通过time.Now()函数获取当前的时间对象,然后获取时间对象的年月日时分秒等信息。

func main() {
	now := time.Now()
	fmt.Printf("当前时间是:%s\n", now.String())
	fmt.Printf("%d年", now.Year())
	fmt.Printf("%d月", now.Month())
	fmt.Printf("%d日", now.Day())
	fmt.Printf("\t%d:", now.Hour())
	fmt.Printf("%d:", now.Minute())
	fmt.Printf("%d", now.Second())
}

Output:

$ go run main.go
当前时间是:2020-05-23 23:12:30.6339153 +0800 CST m=+0.013003701
2020年5月23日   23:12:30

2.时间戳

时间戳是自1970年1月1日(08:00:00GMT)至当前时间的总毫秒数。它也被称为Unix时间戳(UnixTimestamp),我们可以将时间戳转化为我们想要的时间格式。

func main() {
	now := time.Now()            //获取当前时间
	timestamp1 := now.Unix()     //时间戳
	timestamp2 := now.UnixNano() //纳秒时间戳
	fmt.Printf("current timestamp1:%v\n", timestamp1)
	fmt.Printf("current timestamp2:%v\n", timestamp2)
	// 时间戳格式化
	// time.Unix有两个参数,第一个时秒时间戳,另一个是纳秒时间戳
	now2 := time.Unix(timestamp1, 0)
	fmt.Printf("当前时间是:%s\n", now2.String())
	fmt.Printf("%d年", now.Year())
	fmt.Printf("%d月", now.Month())
	fmt.Printf("%d日", now.Day())
	fmt.Printf("\t%d:", now.Hour())
	fmt.Printf("%d:", now.Minute())
	fmt.Printf("%d", now.Second())
}

Output:

$ go run main.go
current timestamp1:1590247321
current timestamp2:1590247321140010600
当前时间是:2020-05-23 23:22:01 +0800 CST
2020年5月23日   23:22:1

3.时间间隔

time.Duration是time包定义的一个类型,它代表两个时间点之间经过的时间,以纳秒为单位。time.Duration表示一段时间间隔,可表示的最长时间段大约290年。

time包中定义的时间间隔类型的常量如下:

const (
	Nanosecond  Duration = 1
	Microsecond          = 1000 * Nanosecond
	Millisecond          = 1000 * Microsecond
	Second               = 1000 * Millisecond
	Minute               = 60 * Second
	Hour                 = 60 * Minute
)

时间间隔在我们实际开发中使用还是比较多的,比如记录一个程序运行了多长时间,在下面写一个demo,为了模拟时间差,里面用到了下面会将的时间操作函数:

func main() {
	now := time.Now() //获取当前时间
	// 时间间隔4000秒
	endTime := now.Add(time.Second * 4000)
	// 计算时间间隔
	Duration := time.Unix(0, endTime.Sub(now).Nanoseconds())
	// 时间戳是自1970年1月1日(08:00:00GMT)至当前时间的总毫秒数,因此给小时减去8就是准确的时间差了
	fmt.Printf("用时: %d小时%d分钟%d秒", Duration.Hour()-8, Duration.Minute(), Duration.Second())
}

Output:

$ go run main.go
用时: 1小时6分钟40秒

4.时间操作

【1】增加时间,这个在上面的例子已经使用了,使用Add方法就可以对时间进行增加的操作。

func main() {
	now := time.Now() //获取当前时间
	fmt.Printf("当前时间是: %s\n", now.String())
	// 时间间隔4000秒, 注意这里时间间隔可以为负数,负数表示时间相减
	BeforeTime := now.Add(-time.Second * 4000)
	fmt.Printf("4000秒前的时间是: %s", BeforeTime.String())
}

Output:

$ go run main.go
当前时间是: 2020-05-23 23:52:31.1246786 +0800 CST m=+0.008997901
4000秒前的时间是: 2020-05-23 22:45:51.1246786 +0800 CST m=-3999.991002099

【2】求事件差,这个在上面的例子中也用到了,使用Sub方法就可以对两个时间进行求差了。

func main() {
	now := time.Now() //获取当前时间
	fmt.Printf("当前时间是: %s\n", now.String())
	// 时间间隔4000秒
	endTime := now.Add(time.Second * 4000)
	// 计算时间间隔,endTime-now
	Duration := time.Unix(0, endTime.Sub(now).Nanoseconds())
	// 时间戳是自1970年1月1日(08:00:00GMT)至当前时间的总毫秒数,因此给小时减去8就是准确的时间差了
	fmt.Printf("用时: %d小时%d分钟%d秒", Duration.Hour()-8, Duration.Minute(), Duration.Second())
}

【3】比较两个时间是否相同。

func main() {
	//获取当前时间
	now := time.Now()
	// 时间间隔4000秒
	EndTime := now.Add(time.Second * 4000)
	fmt.Printf("当前时间是: %s\n", now.String())
	fmt.Printf("EndTime 是: %s\n", EndTime.String())
	if now.Equal(EndTime) {
		fmt.Println("两个时间相同")
	} else {
		fmt.Println("两段时间不相同")
	}
}

Output:

$ go run main.go
当前时间是: 2020-05-24 09:36:26.9891533 +0800 CST m=+0.010997301
EndTime 是: 2020-05-24 10:43:06.9891533 +0800 CST m=+4000.010997301
两段时间不相同

【4】比较两个时间是否前者早于后者。

func main() {
	//获取当前时间
	now := time.Now()
	// 时间间隔4000秒
	EndTime := now.Add(time.Second * 4000)
	fmt.Printf("当前时间是: %s\n", now.String())
	fmt.Printf("EndTime 是: %s\n", EndTime.String())
	if now.Before(EndTime) {
		fmt.Println("当前时间小于EndTime")
	} else {
		fmt.Println("当前时间大于EndTime")
	}
}

Output:

$ go run main.go
当前时间是: 2020-05-24 09:39:59.9618812 +0800 CST m=+0.010003801
EndTime 是: 2020-05-24 10:46:39.9618812 +0800 CST m=+4000.010003801
当前时间小于EndTime

【5】比较两个时间是否前者晚于后者。

func main() {
	//获取当前时间
	now := time.Now()
	// 时间间隔4000秒
	EndTime := now.Add(time.Second * 4000)
	fmt.Printf("当前时间是: %s\n", now.String())
	fmt.Printf("EndTime 是: %s\n", EndTime.String())
	if now.After(EndTime) {
		fmt.Println("当前时间在EndTime之后")
	} else {
		fmt.Println("当前时间在EndTime之前")
	}
}

Output:

$ go run main.go
当前时间是: 2020-05-24 09:41:40.713311 +0800 CST m=+0.011991301
EndTime 是: 2020-05-24 10:48:20.713311 +0800 CST m=+4000.011991301
当前时间在EndTime之前

5.定时器

使用time.Tick(时间间隔)来设置定时器,定时器的本质上是一个通道(channel)。

func main() {
	tick := time.Tick(time.Second)
	for v := range tick {
		//获取当前时间
		fmt.Println("Now: ", time.Now().Second(), "tick: ", v)
	}
}

Output:

$ go run main.go
Now:  5 tick:  2020-05-24 09:46:05.7408253 +0800 CST m=+1.015033901
Now:  6 tick:  2020-05-24 09:46:06.7420162 +0800 CST m=+2.016224801
Now:  7 tick:  2020-05-24 09:46:07.7408322 +0800 CST m=+3.015040801
Now:  8 tick:  2020-05-24 09:46:08.7408017 +0800 CST m=+4.015010301

可以看到这个循环每秒执行一次。

6.时间的格式化

时间类型有一个自带的方法Format进行格式化,需要注意的是Go语言中格式化时间模板不是常见的Y-m-d H:M:S而是使用Go的诞生时间2006年1月2号15点04分(记忆口诀为2006 1 2 3 4)。也许这就是技术人员的浪漫吧。
补充:如果想格式化为12小时方式,需指定PM。

func main() {
	now := time.Now()
	// 格式化的模板为Go的出生时间2006年1月2号15点04分 Mon Jan
	// 24小时制
	fmt.Println(now.Format("2006-01-02 15:04:05.000 Mon Jan"))
	// 12小时制
	fmt.Println(now.Format("2006-01-02 03:04:05.000 PM Mon Jan"))
	fmt.Println(now.Format("2006/01/02 15:04"))
	fmt.Println(now.Format("15:04 2006/01/02"))
	fmt.Println(now.Format("2006/01/02"))
}

Output:

$ go run main.go
2020-05-24 09:50:08.741 Sun May
2020-05-24 09:50:08.741 AM Sun May
2020/05/24 09:50
09:50 2020/05/24
2020/05/24

当然你也可以将字符串解析为你想要的时间格式:

func main() {
	now := time.Now()
	fmt.Println(now)
	// 加载时区
	loc, err := time.LoadLocation("Asia/Shanghai")
	if err != nil {
		fmt.Println(err)
		return
	}
	// 按照指定时区和指定格式解析字符串时间
	timeObj, err := time.ParseInLocation("2006/01/02 15:04:05", "2019/08/04 14:15:20", loc)
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println(timeObj)
}

Output:

$ go run main.go
2020-05-24 09:52:52.7381466 +0800 CST m=+0.009007901
2019-08-04 14:15:20 +0800 CST

7.时间格式

【1】UTC

Universal Time Coordinated 协调世界时,又称世界标准时间。多数的两地时间表都以GMT来表示,但也有些两地时间表上看不到GMT字样,出现的反而是UTC这3个英文字母,究竟何谓UTC?事实上,UTC指的是Coordinated Universal Time- 世界协调时间(又称世界标准时间、世界统一时间),是经过平均太阳时(以格林威治时间GMT为准)、地轴运动修正后的新时标以及以「秒」为单位的国际原子时所综合精算而成的时间,计算过程相当严谨精密,因此若以「世界标准时间」的角度来说,UTC比GMT来得更加精准。其误差值必须保持在0.9秒以内,若大于0.9秒则由位于巴黎的国际地球自转事务中央局发布闰秒,使UTC与地球自转周期一致。所以基本上UTC的本质强调的是比GMT更为精确的世界时间标准,不过对于现行表款来说,GMT与UTC的功能与精确度是没有差别的。

【2】GMT

Greenwich Mean Time 格林尼治平均时
UTC和GMT都与英国伦敦的本地时相同,所以程序中UTC与GMT没什么不同。意思UTC=GMT是相等的

十七世纪,格林威治皇家天文台为了海上霸权的扩张计画而进行天体观测。1675年旧皇家观测所(Old Royal Observatory) 正式成立,到了1884年决定以通过格林威治的子午线作为划分地球东西两半球的经度零度。观测所门口墙上有一个标志24小时的时钟,显示当下的时间,对全球而言,这里所设定的时间是世界时间参考点,全球都以格林威治的时间作为标准来设定时间,这就是我们耳熟能详的「格林威治标准时间」(Greenwich Mean Time,简称G.M.T.)的由来,标示在手表上,则代表此表具有两地时间功能,也就是同时可以显示原居地和另一个国度的时间。

【3】Unix时间戳

在计算机中看到的UTC时间都是从(1970年01月01日 0:00:00)开始计算秒数的。所看到的UTC时间那就是从1970年这个时间点起到具体时间共有多少秒。 这个秒数就是Unix时间戳。

【4】CST时间

CST却同时可以代表如下 4 个不同的时区:
Central Standard Time (USA) UT-6:00
Central Standard Time (Australia) UT+9:30
China Standard Time UT+8:00
Cuba Standard Time UT-4:00

【5】CET

(英語:Central European Time,CET)欧洲中部时间是比世界标准时间(UTC)早一个小时的时区名称之一。它被大部分欧洲国家和部分北非国家采用。冬季时间为UTC+1,夏季欧洲夏令时为UTC+2。

【6】DST

Daylight Saving Time「夏日节约时间」

是指在夏天太阳升起的比较早时,将时钟拨快一小时,以提早日光的使用,在英国则称为夏令时间(Summer Time)。这个构想于1784年由美国班杰明·富兰克林提出来,1915年德国成为第一个正式实施夏令日光节约时间的国家,以削减灯光照明和耗电开支。自此以后,全球以欧洲和北美为主的约70个国家都引用这个做法。目前被划分成两个时区的印度也正在商讨是否全国该统一实行夏令日光节约时间。欧洲手机上也有很多GSM系统的基地台,除了会传送当地时间外也包括夏令日光节约时间,做为手机的时间标准,使用者可以自行决定要开启或关闭。值得注意的是,某些国家有实施「夏日节约时间」的制度,出国时别忘了跟随当地习惯在表上调整一下,这可是机械表没有的功能设计哦!

【7】不同时间的关系

  • UTC=GMT
  • CET=UTC/GMT + 1小时
  • CST=UTC/GMT +8 小时
  • CST=CET+9

猜你喜欢

转载自blog.csdn.net/random_w/article/details/106307973