Golang中的日期与时间
Golang 的日期及时间
Golang 的日期及时间 Golang提供良好的支持与日期和时间的工作。在 Golang,我们不需要任何第三方软件包来管理时间和日期。Go 标准库的 time 包非常容易理解和实现。
Golang 默认的 time.time 时间类型表示具有纳秒精度的时间瞬间。它是一个没有导出字段的结构,这意味着您永远不需要使用点运算符来访问不同的字段。相反,可以使用各种方法来获得所需的数据。
如何得到当前的系统时间?
这是最常出现的问题之一。作为开发人员,我们遇到了许多这样的情况,需要获得系统的当前时间。观察下面的代码,了解如何得到当前的系统时间。
1package main
2
3import (
4 "fmt"
5 "time"
6)
7
8func main() {
9 now := time.Now()
10 fmt.Println("Current time is:", now)
11}
1$ go run current_time.go
2Current time is: 2021-11-03 20:57:06.294753357 +0530 IST m=+0.000030078
正如我们所知,UTC (Universal Coordinated time)被选为主要的时间标准,它避免了时区、夏时制等的混淆。在 Golang中,我们也可以得到当前系统时间(UTC)。让我们通过示例来了解如何以 UTC 表示当前系统时间。
1package main
2
3import (
4 "fmt"
5 "time"
6)
7
8func main() {
9 now := time.Now().UTC()
10 fmt.Println("Current time is:", now)
11}
1$ go run current_time.go
2Current time is: 2021-11-03 15:32:48.441669614 +0000 UTC
日期和时间
我们还可以在 Golang 的 datetime 中访问不同的组件。为了访问年、月、日、小时、分钟和秒,我们可以对时间对象调用不同的函数。让我们通过下面的一个例子来理解。
1package main
2
3import (
4 "fmt"
5 "time"
6)
7
8func main() {
9 now := time.Now()
10
11 fmt.Println("Year:", now.Year())
12 fmt.Println("Month:", now.Month())
13 fmt.Println("Day:", now.Day())
14 fmt.Println("Hour:", now.Hour())
15 fmt.Println("Minute:", now.Minute())
16 fmt.Println("Second:", now.Second())
17 fmt.Println("Nanosecond:", now.Nanosecond())
18}
1$ go run datetime.go
2Year: 2021
3Month: November
4Day: 3
5Hour: 21
6Minute: 21
7Second: 23
8Nanosecond: 806031374
Golang 的日期函数
我们可以为特定的日期创建一个时间对象。我们可以将年、月、日、小时、分钟、秒、纳秒和位置参数传递给 time.Date 函数。
1package main
2
3import (
4 "fmt"
5 "time"
6)
7
8func main() {
9 t := time.Date(2020, time.November, 10, 23, 0, 0, 0, time.UTC)
10 fmt.Printf("Date-time is set to : %s\n", t.Local())
11}
1$ go run date_func.go
2Date-time is set to : 2020-11-11 04:30:00 +0530 IST
使用 Golang 解析和格式化日期时间
日期和时间都可以有多种表示形式,Golang 提供了 parse () 函数来对其进行解析。Go 语言中的 Parse() 函数用于解析格式化的字符串,然后查找它形成的时间值。让我们观察下面的代码示例。在本例中,我们使用 parse() 函数使用布局来解析日期/时间。这个例子取自 Golang 的官方文件。time.Parse() 函数接受一个时间字符串和一个布局作为输入,并尝试创建一个新的 time 对象。
1package main
2
3import (
4 "fmt"
5 "time"
6)
7
8func main() {
9 // Define the layout as constant
10 // Golang parse function will parse the given string in
11 // same format as provided in layout.
12 const longForm = "Jan 2, 2006 at 3:04pm (MST)"
13 t, _ := time.Parse(longForm, "Feb 3, 2013 at 7:54pm (PST)")
14 fmt.Println(t)
15
16 const shortForm = "2006-Jan-02"
17 t, _ = time.Parse(shortForm, "2013-Feb-03")
18 fmt.Println(t)
19
20 // Some valid layouts are invalid time values, due to format specifiers
21 // such as _ for space padding and Z for zone information.
22 // For example the RFC3339 layout 2006-01-02T15:04:05Z07:00
23 // contains both Z and a time zone offset in order to handle both valid options:
24 // 2006-01-02T15:04:05Z
25 // 2006-01-02T15:04:05+07:00
26 t, _ = time.Parse(time.RFC3339, "2006-01-02T15:04:05Z")
27 fmt.Println(t)
28 t, _ = time.Parse(time.RFC3339, "2006-01-02T15:04:05+07:00")
29 fmt.Println(t)
30 _, err := time.Parse(time.RFC3339, time.RFC3339)
31 fmt.Println("error", err) // Returns an error as the layout is not a valid time value
32
33}
1$ go run parse_time.go
22013-02-03 19:54:00 +0000 PST
32013-02-03 00:00:00 +0000 UTC
42006-01-02 15:04:05 +0000 UTC
52006-01-02 15:04:05 +0700 +0700
6error parsing time "2006-01-02T15:04:05Z07:00": extra text: "07:00"
Golang 的持续时间
简单地说,持续时间是两个时刻之间经过的时间。技术上,在Golang持续时间表示两个瞬间之间的经过时间,作为一个整数64纳秒计数。这代表将最长的持续时间限制在大约290年。让我们来看一个例子,如何计算方法调用之间的运行时间。观察下面的代码函数 t1.Sub(t0) 是用来计算运行时间的。
1package main
2
3import (
4 "fmt"
5 "time"
6)
7
8func expensiveCall() {}
9
10func main() {
11 t0 := time.Now()
12 expensiveCall()
13 t1 := time.Now()
14 fmt.Printf("The call took %v to run.\n", t1.Sub(t0))
15}
1$ go run elapsed.go
2The call took 64ns to run.
加减和比较时间
Golang 提供各种功能,可对时间对象执行多种操作。通过这些方法,我们可以添加时间或时间相减,得到两个时间之间的差,并比较两个时间,看看哪个时间在另一个时间之后。让我们通过例子来理解这一点。
在下面的例子中,我们使用了两个函数: time.Add()
加/减去时间 和 time.AddDate()
添加/减去日期。
1package main
2
3import (
4 "fmt"
5 "time"
6)
7
8func main() {
9 // Adding time
10
11 // Adding 5 minutes
12 currentTime := time.Now().UTC()
13 inFiveMinutes := currentTime.Add(time.Minute * 5)
14 fmt.Println("Five min in future", inFiveMinutes)
15
16 // 5 minutes ago
17 fiveMinutesAgo := currentTime.Add(-time.Minute * 5)
18 fmt.Println("Five min in past", fiveMinutesAgo)
19
20
21 // Adds years, months, and days
22
23 // inOneMonth is 1 month in the future
24 inOneMonth := currentTime.AddDate(0, 1, 0)
25 fmt.Println("One month in future", inOneMonth)
26
27
28 oneDayAgo := currentTime.AddDate(0, 0, -1)
29 fmt.Println("One day ago ", oneDayAgo)
30}
1Five min in future 2021-11-05 05:18:53.982233815 +0000 UTC
2Five min in past 2021-11-05 05:08:53.982233815 +0000 UTC
3One month in future 2021-12-05 05:13:53.982233815 +0000 UTC
4One day ago 2021-11-04 05:13:53.982233815 +0000 UTC
现在让我们举一个例子,我们需要得到两个时间实例之间的差。 time.Sub()
获取两个时间实例之间的差。
1package main
2
3import (
4 "fmt"
5 "time"
6)
7
8func main() {
9 // Getting difference between time instances
10 startTime := time.Date(2019, 1, 1, 3, 0, 0, 0, time.UTC)
11 endTime := time.Date(2020, 1, 1, 3, 0, 0, 0, time.UTC)
12
13 difference := endTime.Sub(startTime)
14 fmt.Printf("The time difference is = %v\n", difference)
15}
1$ go run time_diff.go
2The time difference is = 8760h0m0s
现在让我们举一个例子,我们需要找出哪个时间先于其他时间出现, 我们会利用 time.After() 函数。这是非常常见的用例,用于需要比较时间的地方。我们还将看看如何检查时间是否相等–就是使用 time.Equal()
1package main
2
3import (
4 "fmt"
5 "time"
6)
7
8func main() {
9
10 first := time.Date(2022, 2, 1, 3, 0, 0, 0, time.UTC)
11 second := time.Date(2021, 2, 1, 12, 0, 0, 0, time.UTC)
12 third := time.Date(2021, 2, 1, 12, 0, 0, 0, time.UTC)
13
14 isFirstAfter := first.After(second)
15 fmt.Printf("Is first come after %t\n",isFirstAfter)
16 isThirdEqualSecond := third.Equal(second)
17 fmt.Printf("Is third equal second %t\n",isThirdEqualSecond)
18
19}
1$ go run time_check.go
2Is first come after true
3Is third equal second true
Sleep & time ticker
在 Golang中,我们可以使用 time.Sleep() 暂停代码的执行 。请记住,这是同步的,它会阻塞当前 Go 线程(routine)。
1package main
2
3import (
4 "fmt"
5 "time"
6)
7
8func main() {
9 // Sleeping for 5 second
10 fmt.Printf("Current Unix Time: %v\n", time.Now().Unix())
11 time.Sleep(5 * time.Second)
12 fmt.Printf("Current Unix Time: %v\n", time.Now().Unix())
13}
1$ go run sleep_5second.go
2Current Unix Time: 1636090412
3Current Unix Time: 1636090417
Golang ticker 是用来在特定的时间间隔执行代码的。如果我们需要在一个固定的时间间隔内做一些事情(比如说每秒或者每分钟) ,我们可以使用 Golang time.Ticker() 函数。举个例子。在下面的代码中,我们每秒钟打印一次语句。
1package main
2
3import (
4 "fmt"
5 "time"
6)
7
8func printSomethingEverySecond() {
9 ticker := time.NewTicker(time.Second)
10 for range ticker.C {
11 fmt.Printf("Current Unix Time: %v\n", time.Now().Unix())
12 }
13}
14func main() {
15 printSomethingEverySecond()
16}
1$ go run ticker_demo.go
2Current Unix Time: 1636090736
3Current Unix Time: 1636090737
4Current Unix Time: 1636090738
5Current Unix Time: 1636090739
6Current Unix Time: 1636090740
7Current Unix Time: 1636090741
8Current Unix Time: 1636090742
9...