作者选择了 多样性在技术基金作为 写给捐款计划的一部分接受捐款。
介绍
该软件旨在使工作更容易完成,对于许多人来说,这包括与日期和时间进行交互。日期和时间值在现代软件中显示到处。例如,跟踪汽车需要服务时,让车主知道,跟踪数据库中的变化,创建审计日志,或者只是将时间与时间进行比较,以确定过程需要多长时间。
在本教程中,您将创建一个Go程序来获取计算机的当前本地时间,然后在人们更容易阅读的格式上打印到屏幕上。接下来,您将解释一个字符串来提取日期和时间信息。
前提条件
要遵循本教程,您将需要:
- Go 版本 1.16 或更高版本已安装. 若要设置此功能,请遵循 How To Install Go 教程为您的操作系统。
获取当前时间
在本节中,您将使用Go的时间
包获取当前时间。Go的标准库中的时间
包提供了各种与日期和时间相关的函数,并且可以用time.Time
类型来表示特定时间点。
要开始创建一个程序来探索时间
包,你需要为文件创建一个目录. 这个目录可以创建在您的计算机上任何地方,但许多开发者倾向于为他们的项目有一个目录. 在本教程中,你将使用名为项目
的目录。
创建项目
目录并导航到它:
1mkdir projects
2cd projects
从项目
目录中运行mkdir
来创建一个日期
目录,然后使用cd
导航:
1mkdir datetime
2cd datetime
一旦您创建了项目目录,请使用nano
或您喜爱的编辑器打开main.go
文件:
1nano main.go
在main.go
文件中,添加一个main
函数,以获取当前时间并打印它:
1[label projects/datetime/main.go]
2package main
3
4import (
5 "fmt"
6 "time"
7)
8
9func main() {
10 currentTime := time.Now()
11 fmt.Println("The time is", currentTime)
12}
在此程序中,从time
包中使用的time.Now
函数将当前的本地时间作为time.Time
值,然后将其存储在currentTime
变量中。
使用go run
与main.go
文件运行程序:
1go run main.go
显示当前日期和时间的输出将看起来像这样:
1[secondary_label Output]
2The time is 2021-08-15 14:30:45.0000001 -0500 CDT m=+0.000066626
此外,您看到的时区(-0500 CDT
在此输出中)可能会有所不同,因为 time.Now()
返回本地时区中的时间。
您也可以在输出中注意到一个 m=
值. 这个值是 monotonic clock,并且在测量时间差异时被 Go 内部使用。 单调的时钟旨在弥补计算机系统时钟的日期和时间的任何潜在变化,而程序正在运行。 使用单调的时钟,与 time.Now’ 值相比的
time.Now` 值五分钟后仍然会得到正确的结果(五分钟的间隔),即使计算机的系统时钟在五分钟的间隔内改变一个小时前进或后退。 您不需要仔细了解本教程中的代码或示例,但如果您想了解更多关于单调的时钟和 Go 如何使用它们,则《Monotonic Clocks(LINK0)》
现在,虽然显示了当前时间,但对用户来说可能并不有用,它可能不是您正在寻找的格式,或者它可能包含比您想要显示的日期或时间的更多部分。
幸运的是,‘time.Time’类型包括各种方法来获取您想要的日期或时间的特定部分,例如,如果您只想知道‘currentTime’变量的年份,您可以使用‘Year’方法,或者使用‘Hour’方法获取当前时间。
再次打开你的main.go
文件,并将一些time.Time
方法添加到输出中,以查看它们产生的结果:
1[label projects/datetime/main.go]
2...
3
4func main() {
5 currentTime := time.Now()
6 fmt.Println("The time is", currentTime)
7
8 fmt.Println("The year is", currentTime.Year())
9 fmt.Println("The month is", currentTime.Month())
10 fmt.Println("The day is", currentTime.Day())
11 fmt.Println("The hour is", currentTime.Hour())
12 fmt.Println("The minute is", currentTime.Hour())
13 fmt.Println("The second is", currentTime.Second())
14}
接下来,使用go run
再次运行您的程序:
1go run main.go
结果将看起来像这样:
1[secondary_label Output]
2The time is 2021-08-15 14:30:45.0000001 -0500 CDT m=+0.000066626
3The year is 2021
4The month is August
5The day is 15
6The hour is 14
7The minute is 14
8The second is 45
与之前的输出一样,当前的日期和时间将与示例不同,但格式应该相似。这次在输出中,你会看到完整的日期和时间印刷,就像以前一样,但你还有一份年份、月日、月日、小时、分钟和秒的列表。 注意,而不是按月印刷为数字(就像全日期一样),它将显示为英语字符串8月
。
现在,在你的程序中重新更新main.go
文件,并用单个函数调用fmt.Printf
来替换各种函数输出,这样你就可以以更接近你可能想要向用户显示的格式打印当前的日期和时间:
1[label projects/datetime/main.go]
2...
3
4func main() {
5 currentTime := time.Now()
6 fmt.Println("The time is", currentTime)
7
8 fmt.Printf("%d-%d-%d %d:%d:%d\n",
9 currentTime.Year(),
10 currentTime.Month(),
11 currentTime.Day(),
12 currentTime.Hour(),
13 currentTime.Hour(),
14 currentTime.Second())
15}
一旦您将更新保存到main.go文件中,请使用go run
命令运行它,就像以前一样:
1go run main.go
结果将看起来像这样:
1[secondary_label Output]
2The time is 2021-08-15 14:30:45.0000001 -0500 CDT m=+0.000066626
32021-8-15 14:14:45
这个时候你的输出可能更接近你想要的,但仍然有一些东西可以调整的输出. 这个月现在再次出现在数字格式中,因为fmt.Printf
格式使用%d
来告诉time.Month
类型,它应该使用一个数字而不是一个字符串
,但它只出现在单个数字中。 如果你想显示两个数字,你可以更改fmt.Printf
格式来说,但如果你也想显示一个12小时的时间而不是一个24小时的时间,如上面的输出所示? 使用fmt.Printf
方法,你需要做自己的数学来计算它。 使用fmt.Printf
的日期和时间是可能的,但正如你所看到的,它最终可以变成子。 这样做,你可以
在本节中,您创建了一个新的程序,以使用time.Now
来获取当前时间。一旦您有当前时间,您然后使用各种函数,如Year
和Hour
在time.Time
类型上,以打印有关当前时间的信息。它确实开始变得很多工作,以显示它在自定义格式,然而. 为了使这种类型的常见工作更容易,许多编程语言,包括Go,提供一个特殊的方式来格式化日期和时间,类似于如何使用fmt.Printf
来格式化字符串。
打印和格式化特定的日期
除了年
,小时
和其他数据相关的方法,时间
类型提供,它还提供一种称为格式
的方法。格式
方法允许您提供一个布局字符串
,类似于您如何提供fmt.Printf
或fmt.Sprintf
一个格式,这将告诉格式
方法您想要的日期和时间如何打印。
然而,在您使用格式
方法之前,您将更容易地看到格式
如何影响日期和时间的输出,如果它不每次运行程序时发生变化,直到现在,您使用time.Now
来获取当前时间,所以每次运行时会出现不同的数字。
要开始在你的程序中使用time.Date
而不是time.Now
,请重新打开main.go
文件,并更新它以代替time.Now
为time.Date
:
1[label projects/datetime/main.go]
2...
3
4func main() {
5 theTime := time.Date(2021, 8, 15, 14, 30, 45, 100, time.Local)
6 fmt.Println("The time is", theTime)
7}
参数的 time.Date
函数包括年份,月,月日,小时,分钟,第二日期和时间,你想要一个 time.Time
为. 最后两个参数的第一个计算纳米秒,最后一个参数是时间区创建的时间区。
保存更新后,使用go run
来运行您的程序:
1go run main.go
结果将看起来像这样:
1[secondary_label Output]
2The time is 2021-08-15 14:30:45.0000001 -0500 CDT
您看到的输出现在应该更接近上面的输出,因为您在运行程序时使用特定的本地日期和时间,而不是当前的日期和时间(取决于您的计算机设置的时区,时区可能会有所不同)。
使用格式
方法定制日期字符串
许多其他编程语言都包含类似的方式来格式化显示的日期和时间,但Go构建这些格式的布局方式可能略有不同于你在其他语言中使用它们的情况。在其他语言中,日期格式使用类似的方式来格式化 Go 中的Printf
工作,一个%
字符随后是代表日期或时间的一部分的字母。例如,4位数的年份可能代表%Y
年份。在 Go 中,这些日期或时间的部分由代表特定日期的字符表示。要在 Go 日期格式中包含4位数的年份,你实际上会在字符串中包含2006
字符。此布局类型的好处是,你在代码中看到的内容实际上代表了你在输出中看到的内容。当你能够看到
Go 在字符串格式中使用的日期和时间布局的具体日期是 01/02 03:04:05PM '06 -0700`. 如果你查看日期和时间的每个组件,你会看到它们在每个组件中增加一个。 月亮首先是 01 次,然后是月亮的日子是 02 次,然后是 03 次,分钟是 04 次,第二个是 05 次,年份是 06 次(或 2006 次),最后是 07 次的时区。 记住这个顺序将使未来更容易创建日期和时间格式。
现在,使用这个新的格式
方法来复制和清理您在上一节打印的日期格式,需要多个行和函数调用来显示,并且使用格式
方法应该使复制变得更容易和更干净。
打开main.go
文件,添加一个新的fmt.Println
呼叫,并通过使用格式
方法格式化的日期传递给TheTime
:
1[label projects/datetime/main.go]
2...
3
4func main() {
5 theTime := time.Date(2021, 8, 15, 14, 30, 45, 100, time.Local)
6 fmt.Println("The time is", theTime)
7
8 fmt.Println(theTime.Format("2006-1-2 15:4:5"))
9}
如果你看看格式使用的布局,你会看到它使用上面的同一时间来指定日期和时间应该如何格式化(2006年1月2日)。
若要查看此新格式的输出,请保存您的程序并使用go run
运行它:
1go run main.go
结果将看起来像这样:
1[secondary_label Output]
2The time is 2021-08-15 14:30:45.0000001 -0500 CDT
32021-8-15 14:30:45
您现在看到的输出将类似于上一节的末尾输出,但它更容易完成. 您所需要的只是一个单行代码和一个布局字符串。
根据您显示的日期或时间,使用变量长度格式,如您在直接打印数字时使用的格式,可能很难为您自己,您的用户或其他代码读取该值。使用1
为月份格式,将导致3月显示为3
,而10月将使用两个字符并显示为10
。
1[label projects/datetime/main.go]
2...
3
4func main() {
5 theTime := time.Date(2021, 8, 15, 14, 30, 45, 100, time.Local)
6 fmt.Println("The time is", theTime)
7
8 fmt.Println(theTime.Format("2006-1-2 15:4:5"))
9 fmt.Println(theTime.Format("2006-01-02 03:04:05 pm"))
10}
保存代码后,使用go run
再次运行该程序:
1go run main.go
结果将看起来像这样:
1[secondary_label Output]
2The time is 2021-08-15 14:30:45.0000001 -0500 CDT
32021-8-15 14:30:45
42021-08-15 02:30:45 pm
你会看到,通过在布局字符串中添加一个0
前缀,新输出中的月份的8
变成08
,以匹配布局。现在在12小时格式中的时钟也有自己的0
前缀。
很多时候,格式化日期是用来被其他程序解释的,每次想要使用这些格式时重新创建这些格式都可能成为一个负担。
使用预定义格式
有许多常用的日期格式,例如日志消息的时刻印,每次您想要使用它们时重新创建这些格式可能会导致麻烦,在某些情况下,时间
包包括您可以使用的预定义格式。
一个可用的和经常使用的格式是RFC 3339(LINK0)中定义的格式之一。一个 _RFC_是用来定义互联网上的标准是如何工作的文件,然后其他RFC可以相互依赖。有一个RFC定义HTTP的工作方式(RFC 2616),例如,还有其他人建立在上面,以进一步定义HTTP。
在时间
包中的每一个预定义时间格式都以它们所代表的格式命名为const string
。RFC 3339格式有两种可用格式,一种称为time.RFC3339
,另一种称为time.RFC3339Nano
。
现在,重新打开您的 main.go
文件,并更新您的程序以使用 time.RFC3339Nano
格式为其输出:
1[label projects/datetime/main.go]
2...
3
4func main() {
5 theTime := time.Date(2021, 8, 15, 14, 30, 45, 100, time.Local)
6 fmt.Println("The time is", theTime)
7
8 fmt.Println(theTime.Format(time.RFC3339Nano))
9}
由于预定义的格式是具有所需格式的字符串
值,您只需要将您通常使用的格式替换为其中一个。
要查看输出,请重新运行您的程序,然后使用Go Run
:
1go run main.go
结果将看起来像这样:
1[secondary_label Output]
2The time is 2021-08-15 14:30:45.0000001 -0500 CDT
32021-08-15T14:30:45.0000001-05:00
RFC 3339格式是很好的,如果您需要在某个地方保存一个时间值作为一个字符串
,它可以被许多其他编程语言和应用程序读取,并且几乎和日期和时间在灵活的字符串
格式一样紧凑。
在本节中,您更新了您的程序以使用格式
方法来打印日期和时间。使用这种灵活的布局还允许您的代码看起来与最终输出相似。最后,您使用了预定义的布局字符串之一来打印日期和时间,使用受支持的格式。
在字符串中解析日期和时间
开发应用程序时,通常会遇到以字符串
表示的日期值,你需要以某种方式解释它们。有时,你需要知道值的日期部分,有时你可能需要知道时间部分,但其他时候你可能需要整个值。除了使用格式
方法来从时间
值中创建字符串
值,Go时间
包还提供一个time.Parse
函数来将一个字符串
转换为时间
值。
现在,在您的程序中打开main.go
文件,并更新它以使用time.Parse
函数将timeString
解析为time.Time
变量:
1[label projects/datetime/main.go]
2...
3
4func main() {
5 timeString := "2021-08-15 02:30:45"
6 theTime, err := time.Parse("2006-01-02 03:04:05", timeString)
7 if err != nil {
8 fmt.Println("Could not parse time:", err)
9 }
10 fmt.Println("The time is", theTime)
11
12 fmt.Println(theTime.Format(time.RFC3339Nano))
13}
与格式
方法不同,time.Parse
方法还会返回一个潜在的错误
值,如果传输的字符串
值不匹配作为第一个参数提供的布局。
保存更新后,您可以使用去运行
来运行更新的程序:
1go run main.go
结果将看起来像这样:
1[secondary_label Output]
2The time is 2021-08-15 02:30:45 +0000 UTC
32021-08-15T02:30:45Z
有一点要注意在这个输出中。 一点是,从timeString
进行解析的时区正在使用默认时区,这是一个+0
偏差,被称为协调通用时间
(https://en.wikipedia.org/wiki/Coordinated_Universal_Time)(UTC)。既然时间值和布局都没有包含时区,所以time.Parse
函数不知道该关联的时区。如果你在某个时候需要它,但time
包装确实包含一个time.ParseInLocation
(https://pkg.go.dev/time#ParseInLocation)函数,所以你可以提供使用的位置。另一个要注意的部分是在RFC 3339输出中。 输出使用time.RFC3339Nano
布局,但输出不包括任何纳米秒。 这是因为time.Parse
函数不包含任何纳米秒,所以设置的值
time.Parse
方法还可以使用任何在 time
包中提供的预定义时间布局来解析一个 string
值. 要在实践中看到这一点,请打开你的 main.go
文件并更新 timeString
值以匹配以前的 time.RFC3339Nano
的输出,并更新 time.Parse
参数以匹配:
1[label projects/datetime/main.go]
2...
3
4func main() {
5 timeString := "2021-08-15T14:30:45.0000001-05:00"
6 theTime, err := time.Parse(time.RFC3339Nano, timeString)
7 if err != nil {
8 fmt.Println("Could not parse time:", err)
9 }
10 fmt.Println("The time is", theTime)
11
12 fmt.Println(theTime.Format(time.RFC3339Nano))
13}
一旦你更新了代码,你可以保存你的程序,并使用去运行
重新运行它:
1go run main.go
结果将看起来像这样:
1[secondary_label Output]
2The time is 2021-08-15 14:30:45.0000001 -0500 CDT
32021-08-15T14:30:45.0000001-05:00
这一次,从格式
方法的输出显示,time.Parse
能够从timeString
解析时区和纳米秒。
在本节中,您使用了time.Parse
函数来分析任意格式化的日期和时间字符串值以及预定义的布局. 到目前为止,您尚未与您所看到的各种时区进行交互。
与时区合作
在与世界各地的用户一起开发应用程序时,甚至仅跨几个时区,常见的做法是使用 Coordinated Universal Time (UTC) (UTC) 存储日期和时间,然后在需要时转换为用户的本地时间。
在本教程的早期部分中,您创建了一个程序,该程序主要基于您自己的本地时区的时间。 要将您的 time.Time
值保存为 UTC,您首先需要将其转换为 UTC。
<$>[注] **注:**本节将计算机的本地时区和UTC之间的时间转换。
现在,打开你的main.go
文件来更新你的程序,使用UTC
方法在TheTime
返回时间的UTC版本:
1[label projects/datetime/main.go]
2...
3
4func main() {
5 theTime := time.Date(2021, 8, 15, 14, 30, 45, 100, time.Local)
6 fmt.Println("The time is", theTime)
7 fmt.Println(theTime.Format(time.RFC3339Nano))
8
9 utcTime := theTime.UTC()
10 fmt.Println("The UTC time is", utcTime)
11 fmt.Println(utcTime.Format(time.RFC3339Nano))
12}
此时,您的程序在本地时区中创建theTime
作为time.Time
值,以两个不同的格式打印,然后使用UTC
方法将该时间从本地时间转换为UTC时间。
要查看该程序的输出,您可以使用去运行
来运行它:
1go run main.go
结果将看起来像这样:
1[secondary_label Output]
2The time is 2021-08-15 14:30:45.0000001 -0500 CDT
32021-08-15T14:30:45.0000001-05:00
4The UTC time is 2021-08-15 19:30:45.0000001 +0000 UTC
52021-08-15T19:30:45.0000001Z
您的输出将取决于您的本地时区,但在上面的输出中,您将看到第一个打印时间是CDT
(北美中央日光时间),这是5
小时从UTC。
也可以以同樣的方式將 UTC 時間轉換為當地時間,使用「Time.Time」上的「Local」方法。 再次開啟「main.go」檔案,並更新它以在「utcTime」上添加「Local」方法的呼叫,將其轉換回您的當地時區:
1[label projects/datetime/main.go]
2...
3
4func main() {
5 theTime := time.Date(2021, 8, 15, 14, 30, 45, 100, time.Local)
6 fmt.Println("The time is", theTime)
7 fmt.Println(theTime.Format(time.RFC3339Nano))
8
9 utcTime := theTime.UTC()
10 fmt.Println("The UTC time is", utcTime)
11 fmt.Println(utcTime.Format(time.RFC3339Nano))
12
13 localTime := utcTime.Local()
14 fmt.Println("The Local time is", localTime)
15 fmt.Println(localTime.Format(time.RFC3339Nano))
16}
一旦你的文件被保存,运行你的程序使用去运行
:
1go run main.go
结果将看起来像这样:
1[secondary_label Output]
2The time is 2021-08-15 14:30:45.0000001 -0500 CDT
32021-08-15T14:30:45.0000001-05:00
4The UTC time is 2021-08-15 19:30:45.0000001 +0000 UTC
52021-08-15T19:30:45.0000001Z
6The Local time is 2021-08-15 14:30:45.0000001 -0500 CDT
72021-08-15T14:30:45.0000001-05:00
在上面的输出中,UTC转换回CDT意味着从UTC中扣除了五个小时,将时间从19
更改为14
。
在本节中,您更新了程序以使用UTC
方法将本地时间区和标准UTC时间区之间的日期和时间转换,然后再使用本地
方法返回。
一旦你有你的日期和时间值可用,Go时间
包提供了一些额外的功能,可以在你的应用程序中有用。
两次比较
比较两个日期可能有时是错误的困难,因为所有变量需要考虑在比较它们时,例如,需要考虑时区,或事实上,月份有不同的天数。
时间
包提供两种方法来简化这些比较:在time.Time
类型上可用的之前
和之后
方法,这些方法都接受单一的时间值,并返回真实
或错误
,取决于他们被调用的时间是否在提供的时间之前或之后。
若要查看这些函数的示例,请打开main.go
文件并将其更新为包含两个不同的日期,然后使用前
和后
来比较这些日期以查看输出:
1[label projects/datetime/main.go]
2...
3
4func main() {
5 firstTime := time.Date(2021, 8, 15, 14, 30, 45, 100, time.UTC)
6 fmt.Println("The first time is", firstTime)
7
8 secondTime := time.Date(2021, 12, 25, 16, 40, 55, 200, time.UTC)
9 fmt.Println("The second time is", secondTime)
10
11 fmt.Println("First time before second?", firstTime.Before(secondTime))
12 fmt.Println("First time after second?", firstTime.After(secondTime))
13
14 fmt.Println("Second time before first?", secondTime.Before(firstTime))
15 fmt.Println("Second time after first?", secondTime.After(firstTime))
16}
一旦你更新了你的文件,保存它,并使用去运行
运行它:
1go run main.go
结果将看起来像这样:
1[secondary_label Output]
2The first time is 2021-08-15 14:30:45.0000001 +0000 UTC
3The second time is 2021-12-25 16:40:55.0000002 +0000 UTC
4First time before second? true
5First time after second? false
6Second time before first? false
7Second time after first? true
由于代码使用的是 UTC 时区中的明确日期,所以您的输出应与上面的输出匹配。 您会看到,当您在 firstTime
上使用Before
方法并提供secondTime
来比较时,它表示2021-08-15
在2021-12-25
之前是真的
。 当您使用After
方法的firstTime
并提供secondTime
时,它表示2021-08-15
在2021-12-25
之后是假
。
另一种方法是将两个日期和时间与时间
包进行比较,是Sub
方法。Sub
方法会从另一个日期中抽取一个日期,并使用新类型time.Duration
返回一个值。与time.Duration
值不同,该值代表时间的绝对点,而time.Duration
值代表时间的差异。例如,在一个小时内
将是一个持续时间,因为它意味着基于当天时间的不同,但在中午
代表一个特定的绝对时间。
现在,更新您的main.go
文件以在firstTime
和secondTime
值上使用Sub
方法,并打印结果:
1[label projects/datetime/main.go]
2...
3
4func main() {
5 firstTime := time.Date(2021, 8, 15, 14, 30, 45, 100, time.UTC)
6 fmt.Println("The first time is", firstTime)
7
8 secondTime := time.Date(2021, 12, 25, 16, 40, 55, 200, time.UTC)
9 fmt.Println("The second time is", secondTime)
10
11 fmt.Println("Duration between first and second time is", firstTime.Sub(secondTime))
12 fmt.Println("Duration between second and first time is", secondTime.Sub(firstTime))
保存你的文件,然后使用go run
运行它:
1go run main.go
结果将看起来像这样:
1[secondary_label Output]
2The first time is 2021-08-15 14:30:45.0000001 +0000 UTC
3The second time is 2021-12-25 16:40:55.0000002 +0000 UTC
4Duration between first and second time is -3170h10m10.0000001s
5Duration between second and first time is 3170h10m10.0000001s
上面的输出表示,两个日期之间有3170小时,10分钟,10秒,100纳秒,并且有几点要注意的输出。第一个是,第一次和第二次之间的持续时间是一个负值。这意味着第二次是在第一次之后,并且类似于如果你从0
中扣除5
并获得5
。第二件事要注意的是,一个持续时间的最大测量单位是一个小时,所以它不会把它分解成几天或几个月。由于一个月的天数不一致,而一天
在更换日光节省时间时可能会有不同的含义,一个小时是最准确的测量,肯定不会波动。
在本节中,您更新了您的程序以使用三种不同的方法进行两次比较。首先,您使用了前
和后
方法来确定一个时间是否在另一个时间之前或之后,然后您使用了Sub
来查看两次之间的时间。
添加或扣除时间
在撰写应用程序时,使用日期和时间的一个常见操作是根据另一个时间确定过去或未来的时间。 它可以用于功能,例如确定订阅何时会下次更新,或者如果某些值被检查后已经过了一段时间。
创建一个time.Duration
值类似于在纸上写一个持续时间,只需以时间单位的倍数。例如,要创建一个time.Duration
来表示一个小时,你会使用time.Hour
值来定义它,以你想要的time.Duration
来表示的小时数倍:
1oneHour := 1 * time.Hour
2twoHours := 2 * time.Hour
3tenHours := 10 * time.Hour
声明较小的时间单位以类似的方式处理,但使用time.Minute
,time.Second
,等等:
1tenMinutes := 10 * time.Minute
2fiveSeconds := 5 * time.Second
一个持续时间也可以添加到另一个持续时间来获取持续时间的总和. 若要在动作中看到这一点,请打开你的 main.go
文件并更新它以声明一个 toAdd
持续时间变量并添加不同的持续时间:
1[label projects/datetime/main.go]
2...
3
4func main() {
5 toAdd := 1 * time.Hour
6 fmt.Println("1:", toAdd)
7
8 toAdd += 1 * time.Minute
9 fmt.Println("2:", toAdd)
10
11 toAdd += 1 * time.Second
12 fmt.Println("3:", toAdd)
13}
完成更新后,保存文件并使用去运行
运行您的程序:
1go run main.go
结果将看起来像这样:
1[secondary_label Output]
21: 1h0m0s
32: 1h1m0s
43: 1h1m1s
当你查看输出时,你会看到打印的第一个持续时间为一个小时,对应于你的代码中的1 * time.Hour
。接下来,你将1 * time.Minute
添加到ToAdd
值中,显示为一个小时,一个分钟的值。
还可以将持续时间合并到一个陈述中,或者从另一个陈述中提取一个持续时间:
1oneHourOneMinute := 1 * time.Hour + 1 * time.Minute
2tenMinutes := 1 * time.Hour - 50 * time.Minute
接下来,打开你的main.go
文件,并更新你的程序,使用这样的组合,从添加
中提取一分钟和一秒:
1[label projects/datetime/main.go]
2...
3
4func main() {
5
6 ...
7
8 toAdd += 1 * time.Second
9 fmt.Println("3:", toAdd)
10
11 toAdd -= 1*time.Minute + 1*time.Second
12 fmt.Println("4:", toAdd)
13}
保存代码后,您可以使用go run
来运行该程序:
1go run main.go
结果将看起来像这样:
1[secondary_label Output]
21: 1h0m0s
32: 1h1m0s
43: 1h1m1s
54: 1h0m0s
新的第四行添加到输出中显示了你包含的新的代码,以减去1 * time.Minute
和1 * time.Second
的总和正确工作,结果是原始的1小时值再次出现。
使用这些持续时间与添加
方法相结合的time.Time
类型允许你采取你已经拥有的时间值,并确定在该时间之前或之后的任何其他任意时刻的时间。 要看到一个例子,打开你的main.go
文件,并更新它以将添加
值设置为24小时,或24 * time.Hour
。
1[label projects/datetime/main.go]
2...
3
4func main() {
5 theTime := time.Date(2021, 8, 15, 14, 30, 45, 100, time.UTC)
6 fmt.Println("The time is", theTime)
7
8 toAdd := 24 * time.Hour
9 fmt.Println("Adding", toAdd)
10
11 newTime := theTime.Add(toAdd)
12 fmt.Println("The new time is", newTime)
13}
保存檔案後,請使用「go run」執行您的程式:
1go run main.go
结果将看起来像这样:
1[secondary_label Output]
2The time is 2021-08-15 14:30:45.0000001 +0000 UTC
3Adding 24h0m0s
4The new time is 2021-08-16 14:30:45.0000001 +0000 UTC
看看输出,你会看到,将24小时添加到2021-08-15
的结果是2021-08-16
的新日期。
若要抽出时间,你还会使用添加
方法,这种方法略有反直观性. 由于Sub
方法用于获取两个日期之间的时间差异,你可以使用添加
以负值从time.Time
值中抽出时间。
再次,要在你的程序中看到这个运行,打开你的 main.go
文件,并更新它以将24小时的 toAdd
值更改为负值:
1[label projects/datetime/main.go]
2...
3
4func main() {
5 theTime := time.Date(2021, 8, 15, 14, 30, 45, 100, time.UTC)
6 fmt.Println("The time is", theTime)
7
8 toAdd := -24 * time.Hour
9 fmt.Println("Adding", toAdd)
10
11 newTime := theTime.Add(toAdd)
12 fmt.Println("The new time is", newTime)
13}
保存文件后,再一次使用去运行
来运行您的程序:
1go run main.go
结果将看起来像这样:
1[secondary_label Output]
2The time is 2021-08-15 14:30:45.0000001 +0000 UTC
3Adding -24h0m0s
4The new time is 2021-08-14 14:30:45.0000001 +0000 UTC
这次在输出中,你会看到,而不是将24小时添加到原始时间,新的日期比原始时间提前24小时。
在本节中,您使用time.Hour
,time.Minute
和time.Second
来创建不同程度的time.Duration
值,您还使用了time.Duration
值与添加
方法,以获得原始值之前和之后的新time.Minute
值。
结论
在本教程中,您使用time.Now
来检索计算机上当前本地时间的time.Time
值,然后使用Year
,Month
,Hour
和其他方法访问有关该时间的特定信息。然后,您使用Format
方法来打印使用自定义格式和预定义格式的时间。接下来,您使用time.Parse
函数来解释其中包含的时间的字符串
值,并从中提取时间值。一旦您有时间值,您使用UTC
和Local
方法来翻译时间与本地时间区之间的时间。
使用本教程中描述的各种功能和方法在您的应用程序中将走很长的路,但Go time
包还包括一些其他功能,如果您感兴趣。
本教程也是 DigitalOcean How to Code in Go系列的一部分,该系列涵盖了许多 Go 主题,从首次安装 Go 到如何使用语言本身。