Go语言学习笔记(二十三)
一、Go语言时间编程
1 时间元素编程
Go语言提供了time包来方便我们使用和时间有关的编程
package main
import (
"fmt"
"time"
)
func main() {
fmt.Println(time.Now())
}
一个简单的例子如上,在这个例子中,我们使用了time库里的Now()函数打印了系统显示的当前时间,但是如果我们手动修改时间的话,显示的最终的时间将会发生改变。因此一般情况下我们选择安装将时间与网络时钟同步的服务,网络时间协议(Network Time Protocol,NTP)是一种在整个网络中同步时间的网络协议,使用NTP的不同计算机更有可能就时间达成一致,但在本地他们依然可以设置不同的时区。
2 让程序休眠
Go语言使用Sleep函数让程序休眠,程序休眠期间什么事情都不做,如果Goroutine处于休眠状态,则程序的其他部分可继续执行。如下例:
package main
import (
"fmt"
"time"
)
func main() {
time.Sleep(3 * time.Second)
fmt.Println("I'm awake")
}
为了让程序暂停一会儿,休眠是很有用的。可通过休眠来等待其他任务完成或让程序暂停执行。但除非只是想让程序暂停一会儿,否则使用Goroutine来管理执行流程是更佳的选择。
3 设置超时时间
After函数帮助我们设置在一定的时间后触发动作:
package main
import (
"fmt"
"time"
)
func main() {
fmt.Println("You have two seconds to calculate 19 * 4")
for {
select {
case <-time.After(2 * time.Second):
fmt.Println("Time's up! The answer is 74. Did you get it?")
return
}
}
}
4 使用ticker
使用ticker可让代码每个特定的时间就重复执行一次。需要在很长的时间内定期执行任务时,这么做很有用。
package main
import (
"fmt"
"time"
)
func main() {
c := time.Tick(5 * time.Second)
for t := range c {
fmt.Printf("The time is now %v\n", t)
}
}
5 以字符串格式表示时间
这是不同的时间标准及其字符串表示法
通常,使用上述标准将日期存储在数据库中,并以字符串的方式提供他们。Go语言支持时间标准,也支持定义不同的时间格式。
如下面的实例,将一个使用RFC3339格式的时间字符串传递给了结构体Time,再将这个结构体打印到终端
package main
import (
"fmt"
"log"
"time"
)
func main() {
s := "2006-01-02T15:04:05+07:00"
t, err := time.Parse(time.RFC3339, s)
if err != nil {
log.Fatal(err)
}
fmt.Println(t)
}
6 使用结构体Time
下面的程序演示了结构体Time的一些方法:
package main
import (
"fmt"
"log"
"time"
)
func main() {
s := "2006-01-02T15:04:05+07:00"
t, err := time.Parse(time.RFC3339, s)
if err != nil {
log.Fatal(err)
}
fmt.Printf("The hour is %v\n", t.Hour())
fmt.Printf("The minute is %v\n", t.Minute())
fmt.Printf("The second is %v\n", t.Second())
fmt.Printf("The day is %v\n", t.Day())
fmt.Printf("The month is %v\n", t.Month())
fmt.Printf("UNIX time is %v\n", t.Unix())
fmt.Printf("The day of the week is %v\n", t.Weekday())
}
7 时间加减
方法Add和Sub在既有时间的基础上加减一定的时间,我们将结果赋给变量。
s := "2006-01-02T15:01:05+07:00"
t,err := time.Parse(time.RFC3339,s)
if err != nil{
log.Fatal(err)
}
nt:=t.Add(2*time.Second)
8 比较两个不同的Time结构体
time包提供了方法Before、After和Equal用来不叫两个Time结构体,并返回一个布尔值
package main
import (
"fmt"
"log"
"time"
)
func main() {
s1 := "2017-09-03T18:00:00+00:00"
s2 := "2017-09-04T18:00:00+00:00"
today, err := time.Parse(time.RFC3339, s1)
if err != nil {
log.Fatal(err)
}
tomorrow, err := time.Parse(time.RFC3339, s2)
if err != nil {
log.Fatal(err)
}
fmt.Println(today.After(tomorrow))
fmt.Println(today.Before(tomorrow))
fmt.Println(today.Equal(tomorrow))
}
9 相关问题
9.1 可以相信计算机上的时间吗?
计算机上的时间很容易被设置错误。计算机上用户设置的时区可能是错误的,设置的时间也可能与实际时间相差甚远。所以在我们使用的服务器上务必安装网络时间协议等服务。
9.2 该使用哪种时间格式?
在计算机出现前,格林尼治标准时间就被全球用作共同的时间参考点。UTC使用的是ISO 8601格式。RFC3339是一个ISO 8601拓展。这两种标准都是不错的选择。
9.3 该将UTC还是GMT作为网络时间?
当前,计算机和互联网都将使用时间标准UTC。GMT实际上是一个时区,而从理论上来说,时区受时间调整的影响,而时间标准不会。虽然主流社会将GMT视为一种时间标准,但计算和科学领域当前使用的是UTC。
9.4 挂壁钟和单调时钟之间有何不同
挂壁钟显示的时间受时区和时间调整的影响,并不适合用来度量时间。单调时钟是稳定的,适合用来度量时间。
9.5 如何消除影响计算机上时间的变数,以确保时间一致性?
通过使用网络时间协议(NTP),可与网上的服务器同步时间,还可以用来检查时间误差。
9.6 让Goroutine休眠有何影响?这会导致其他Goroutine停止执行吗?
让Goroutine休眠,将导致它暂停执行,即什么都不做,但其他Goroutine可继续执行。
参考书籍
[1]: 【Go语言入门经典】[英] 乔治·奥尔波 著 张海燕 译