跳转到主要内容

标签(标签)

资源精选(342) Go开发(108) Go语言(103) Go(99) angular(82) LLM(75) 大语言模型(63) 人工智能(53) 前端开发(50) LangChain(43) golang(43) 机器学习(39) Go工程师(38) Go程序员(38) Go开发者(36) React(33) Go基础(29) Python(24) Vue(22) Web开发(20) Web技术(19) 精选资源(19) 深度学习(19) Java(18) ChatGTP(17) Cookie(16) android(16) 前端框架(13) JavaScript(13) Next.js(12) 安卓(11) typescript(10) 资料精选(10) NLP(10) 第三方Cookie(9) Redwoodjs(9) LLMOps(9) Go语言中级开发(9) 自然语言处理(9) 聊天机器人(9) PostgreSQL(9) 区块链(9) mlops(9) 安全(9) 全栈开发(8) ChatGPT(8) OpenAI(8) Linux(8) AI(8) GraphQL(8) iOS(8) 软件架构(7) Go语言高级开发(7) AWS(7) C++(7) 数据科学(7) whisper(6) Prisma(6) 隐私保护(6) RAG(6) JSON(6) DevOps(6) 数据可视化(6) wasm(6) 计算机视觉(6) 算法(6) Rust(6) 微服务(6) 隐私沙盒(5) FedCM(5) 语音识别(5) Angular开发(5) 快速应用开发(5) 提示工程(5) Agent(5) LLaMA(5) 低代码开发(5) Go测试(5) gorm(5) REST API(5) 推荐系统(5) WebAssembly(5) GameDev(5) CMS(5) CSS(5) machine-learning(5) 机器人(5) 游戏开发(5) Blockchain(5) Web安全(5) Kotlin(5) 低代码平台(5) 机器学习资源(5) Go资源(5) Nodejs(5) PHP(5) Swift(5) 智能体(4) devin(4) Blitz(4) javascript框架(4) Redwood(4) GDPR(4) 生成式人工智能(4) Angular16(4) Alpaca(4) SAML(4) JWT(4) JSON处理(4) Go并发(4) kafka(4) 移动开发(4) 移动应用(4) security(4) 隐私(4) spring-boot(4) 物联网(4) nextjs(4) 网络安全(4) API(4) Ruby(4) 信息安全(4) flutter(4) 专家智能体(3) Chrome(3) CHIPS(3) 3PC(3) SSE(3) 人工智能软件工程师(3) LLM Agent(3) Remix(3) Ubuntu(3) GPT4All(3) 软件开发(3) 问答系统(3) 开发工具(3) 最佳实践(3) RxJS(3) SSR(3) Node.js(3) Dolly(3) 移动应用开发(3) 编程语言(3) 低代码(3) IAM(3) Web框架(3) CORS(3) 基准测试(3) Go语言数据库开发(3) Oauth2(3) 并发(3) 主题(3) Theme(3) earth(3) nginx(3) 软件工程(3) azure(3) keycloak(3) 生产力工具(3) gpt3(3) 工作流(3) C(3) jupyter(3) 认证(3) prometheus(3) GAN(3) Spring(3) 逆向工程(3) 应用安全(3) Docker(3) Django(3) R(3) .NET(3) 大数据(3) Hacking(3) 渗透测试(3) C++资源(3) Mac(3) 微信小程序(3) Python资源(3) JHipster(3) 大型语言模型(2) 语言模型(2) 可穿戴设备(2) JDK(2) SQL(2) Apache(2) Hashicorp Vault(2) Spring Cloud Vault(2) Go语言Web开发(2) Go测试工程师(2) WebSocket(2) 容器化(2) AES(2) 加密(2) 输入验证(2) ORM(2) Fiber(2) Postgres(2) Gorilla Mux(2) Go数据库开发(2) 模块(2) 泛型(2) 指针(2) HTTP(2) PostgreSQL开发(2) Vault(2) K8s(2) Spring boot(2) R语言(2) 深度学习资源(2) 半监督学习(2) semi-supervised-learning(2) architecture(2) 普罗米修斯(2) 嵌入模型(2) productivity(2) 编码(2) Qt(2) 前端(2) Rust语言(2) NeRF(2) 神经辐射场(2) 元宇宙(2) CPP(2) 数据分析(2) spark(2) 流处理(2) Ionic(2) 人体姿势估计(2) human-pose-estimation(2) 视频处理(2) deep-learning(2) kotlin语言(2) kotlin开发(2) burp(2) Chatbot(2) npm(2) quantum(2) OCR(2) 游戏(2) game(2) 内容管理系统(2) MySQL(2) python-books(2) pentest(2) opengl(2) IDE(2) 漏洞赏金(2) Web(2) 知识图谱(2) PyTorch(2) 数据库(2) reverse-engineering(2) 数据工程(2) swift开发(2) rest(2) robotics(2) ios-animation(2) 知识蒸馏(2) 安卓开发(2) nestjs(2) solidity(2) 爬虫(2) 面试(2) 容器(2) C++精选(2) 人工智能资源(2) Machine Learning(2) 备忘单(2) 编程书籍(2) angular资源(2) 速查表(2) cheatsheets(2) SecOps(2) mlops资源(2) R资源(2) DDD(2) 架构设计模式(2) 量化(2) Hacking资源(2) 强化学习(2) flask(2) 设计(2) 性能(2) Sysadmin(2) 系统管理员(2) Java资源(2) 机器学习精选(2) android资源(2) android-UI(2) Mac资源(2) iOS资源(2) Vue资源(2) flutter资源(2) JavaScript精选(2) JavaScript资源(2) Rust开发(2) deeplearning(2) RAD(2)

介绍

软件旨在使工作更容易完成,对许多人来说,这包括与日期和时间交互。日期和时间值在现代软件中随处可见。例如,跟踪汽车何时需要维修并让车主知道,跟踪数据库中的更改以创建审核日志,或者只是将一个时间与另一个时间进行比较以确定一个过程需要多长时间。因此,检索当前时间、操纵时间值以从中提取信息,并以易于理解的格式将其显示给用户是应用程序的基本属性。

在本教程中,您将创建一个Go程序来获取计算机的当前本地时间,然后以更易于阅读的格式将其打印到屏幕上。接下来,您将解释一个字符串以提取日期和时间信息。您还将转换两个时区之间的日期和时间值,以及加减时间值以确定两个时间之间的间隔。

先决条件

要遵循本教程,您需要:

  • 安装1.16或更高版本。要设置此设置,请遵循操作系统的“如何安装Go”教程。

获取当前时间

在本节中,您将使用Go的时间包获得当前时间。Go标准库中的时间包提供了各种与日期和时间相关的函数,可以用来表示使用时间的特定时间点。时间类型。除了时间和日期,它还可以保存有关所表示的日期和时间所在的时区的信息。

要开始创建一个程序来浏览时间包,您需要为文件创建一个目录。这个目录可以在您计算机上的任何地方创建,但许多开发人员倾向于为他们的项目创建一个目录。在本教程中,您将使用名为projects的目录。

创建项目目录并导航到:

mkdir projects
cd projects

从项目目录中,运行mkdir创建一个datetime目录,然后使用cd导航到该目录:

mkdir datetime

cd datetime

创建项目目录后,打开主目录。使用nano或您首选的编辑器打开文件:

nano main.go

总的来说。go文件,添加一个主函数,该函数将获取当前时间并打印出来:

package main

import (
	"fmt"
	"time"
)

func main() {
	currentTime := time.Now()
	fmt.Println("The time is", currentTime)
}

在这个节目中,时间。现在,时间包中的函数用于获取当前本地时间作为时间。时间值,然后将其存储在currentTime变量中。一旦它存储在变量fmt中。Println函数使用时间将当前时间打印到屏幕。时间的默认字符串输出格式。

使用go-Run with main运行程序。go文件:

  1. go run main.go

显示当前日期和时间的输出如下所示:

Output
The time is 2021-08-15 14:30:45.0000001 -0500 CDT m=+0.000066626

输出将显示您当前的日期和时间,这与示例不同。此外,您看到的时区(此输出中的-0500 CDT)可能会有所不同,因为时间不同。Now()返回本地时区的时间。

您可能还会注意到输出中有一个m=值。该值是单调时钟,Go在内部测量时间差时使用。单调时钟设计用于补偿程序运行时计算机系统时钟的日期和时间的任何潜在变化。通过使用单调的时钟,一个时间。现在的价值与时间相比较。现在,即使计算机的系统时钟在五分钟间隔期间向前或向后改变一小时,五分钟后的值仍将得到正确的结果(五分钟间隔)。对于本教程中的代码或示例,您不需要完全理解它,但如果您想了解有关单调时钟以及Go如何使用它们的更多信息,时间包文档中的“单调时钟”部分提供了更多详细信息。

现在,虽然您确实显示了当前时间,但它可能对用户没有用处。它可能不是您想要的格式,或者它可能包含比您想要显示的日期或时间更多的部分。

幸运的是,时间到了。时间类型包括获取所需日期或时间的特定部分的各种方法。例如,如果您只想知道currentTime变量的年份部分,可以使用year方法,或者使用hour方法获取当前小时。

打开main.go。再次打开文件,添加一些时间。时间方法到您的输出,以查看它们产生的结果:

...

func main() {
    currentTime := time.Now()
    fmt.Println("The time is", currentTime)
    
    fmt.Println("The year is", currentTime.Year())
    fmt.Println("The month is", currentTime.Month())
    fmt.Println("The day is", currentTime.Day())
    fmt.Println("The hour is", currentTime.Hour())
    fmt.Println("The minute is", currentTime.Hour())
    fmt.Println("The second is", currentTime.Second())
}

接下来,使用go-run再次运行程序:

go运行main.go

输出如下:

Output
The time is 2021-08-15 14:30:45.0000001 -0500 CDT m=+0.000066626
The year is 2021
The month is August
The day is 15
The hour is 14
The minute is 14
The second is 45

与前面的输出一样,您当前的日期和时间将与示例不同,但格式应该类似。这一次在输出中,您将看到以前打印的完整日期和时间,但您还可以看到年、月、日、小时、分钟和秒的列表。请注意,月份不是打印为数字(就像在完整日期中一样),而是显示为英文字符串August。这是因为Month方法返回月份作为时间。Month类型而不仅仅是一个数字,并且该类型被设计为在打印为字符串时打印出完整的英文名称。

现在,再次更新程序中的main.go文件,并用对fmt.Printf的单个函数调用替换各种函数输出,这样您就可以以更接近于您可能希望显示给用户的格式打印当前日期和时间:

...

func main() {
    currentTime := time.Now()
    fmt.Println("The time is", currentTime)
    
    fmt.Printf("%d-%d-%d %d:%d:%d\n",
        currentTime.Year(),
        currentTime.Month(),
        currentTime.Day(),
        currentTime.Hour(),
        currentTime.Hour(),
        currentTime.Second())
}

将更新保存到主目录后。go文件,像以前一样使用go-run命令运行它:

  1. go run main.go

输出如下:

Output
The time is 2021-08-15 14:30:45.0000001 -0500 CDT m=+0.000066626
2021-8-15 14:14:45

这一次,您的输出可能更接近您想要的,但仍有一些东西可以调整输出。月份现在再次以数字格式显示,因为fmt。Printf格式使用%d表示时间。月份类型它应该使用数字而不是字符串,但它只显示为一个数字。如果要显示两位数字,可以更改格式。Printf格式可以这么说,但如果您还想显示12小时时间,而不是上面输出中显示的24小时时间,该怎么办?使用fmt。Printf方法,你必须自己计算。使用格式打印日期和时间。Printf是可能的,但正如你所看到的,它最终会变得麻烦。这样做,您可能会为要显示的每个部分生成大量的行,或者需要进行大量的计算来确定要显示的内容。

在本节中,您创建了一个新程序,以使用time.Now获取当前时间。一旦你有了当前时间,你就可以使用各种功能,比如时间上的年和小时。打印当前时间信息的时间类型。不过,以自定义格式显示它确实开始成为一项繁重的工作。为了使这类常见的工作更容易,包括Go在内的许多编程语言都提供了一种特殊的日期和时间格式,类似于fmt。Printf可用于格式化字符串。

打印和格式化特定日期

除了年份、小时和其他数据相关的时间方法。时间类型提供了,它还提供了一个名为Format的方法。Format方法允许您提供布局字符串,类似于您提供fmt的方式。打印或格式。Sprintf格式,它将告诉format方法您希望如何打印日期和时间。在本节中,您将复制在上一节中添加的时间输出,但要使用Format方法以更简洁的方式。

不过,在使用Format方法之前,如果每次运行程序时格式都不改变,那么可以更容易地了解格式对日期和时间输出的影响。直到现在,你都在用时间获取当前时间。现在,每次跑步时都会出现不同的数字。Go-time包提供了另一个有用的函数,时间。Date函数,它允许您指定时间的特定日期和时间。代表的时间到了。

开始利用时间。日期而不是时间。现在在程序中,打开主窗口。再次打开文件并更新它以替换时间。现在是时候了。日期:

...

func main() {
    theTime := time.Date(2021, 8, 15, 14, 30, 45, 100, time.Local)
    fmt.Println("The time is", theTime)
}

时间的参数。日期函数包括您想要时间的日期和时间的年、月、日、小时、分钟和秒。时间到了。最后两个参数中的第一个占纳秒,最后一个参数是创建时间的时区。本教程后面将介绍使用时区本身。

保存更新后,使用go run运行程序:

  1. go run main.go

输出如下:

Output
The time is 2021-08-15 14:30:45.0000001 -0500 CDT

您看到的输出现在应该更接近上面的输出,因为您在运行程序时使用的是特定的本地日期和时间,而不是当前的日期和时间。(不过,根据您的计算机设置的时区,时区的显示可能会有所不同。)输出格式仍然与您之前看到的格式相似,因为它仍然使用默认时间。时间格式。现在您有了一个标准的日期和时间,可以使用它开始调整使用Format方法显示时间时的格式。

使用Format方法自定义日期字符串

许多其他编程语言都有类似的方式来设置要显示的日期和时间的格式,但Go构造这些格式的布局的方式可能与您在其他语言中使用过的方式略有不同。在其他语言中,日期格式使用与Printf在Go中的工作方式类似的样式,%字符后跟一个字母,表示要插入的日期或时间部分。例如,4位数的年份可以用%Y表示。然而,在Go中,日期或时间的这些部分由代表特定日期的字符表示。要在Go日期格式中包含4位数字的年份,您实际上需要在字符串本身中包含2006年。这种布局的好处是,您在代码中看到的内容实际上代表了您在输出中看到的东西。当您能够看到输出的表示形式时,可以更容易地再次检查您的格式是否与您要查找的格式匹配,也可以让其他开发人员更容易地理解程序的输出,而无需先运行该程序。

Go在字符串格式中用于日期和时间布局的特定日期是01/02 03:04:05PM'06-0700。如果你查看日期和时间的每个组成部分,你会发现它们每个部分增加一个。月份首先是01,然后是02的月份,然后是03的小时,04的分钟,05的第二个,06的年份(或2006),最后是07的时区。记住这个顺序将使以后创建日期和时间格式更加容易。可用于格式化的选项示例也可以在Go的时间包文档中找到。

现在,使用这个新的Format方法复制并清理上一节中打印的日期格式。它需要几行和函数调用才能显示,使用Format方法应该会使复制更容易、更干净。

打开总管。转到文件并添加新的fmt。Println调用并传递带有使用Format方法格式化的日期的时间:

...

func main() {
    theTime := time.Date(2021, 8, 15, 14, 30, 45, 100, time.Local)
    fmt.Println("The time is", theTime)

    fmt.Println(theTime.Format("2006-1-2 15:4:5"))
}

如果您查看用于格式的布局,您会发现它使用了上面的相同时间来指定日期和时间的格式(2006年1月2日)。需要注意的一点是,小时使用的是15,而不是前一个例子中的03。这表明您希望以24小时格式而不是12小时格式显示小时。

要查看此新格式的输出,请保存程序并使用go-run运行:

  1. go run main.go

输出如下:

Output
The time is 2021-08-15 14:30:45.0000001 -0500 CDT
2021-8-15 14:30:45

您现在看到的输出与上一节末尾的输出类似,但实现起来要简单得多。您只需要包含一行代码和一个布局字符串。Format函数为您完成其余操作。

根据您显示的日期或时间,使用像直接打印数字时那样的可变长度格式可能会让您自己、您的用户或其他试图读取数值的代码难以读取。使用1作为月份格式将导致三月显示为3,而十月将使用两个字符并显示为10。现在,打开main。去用另一个更结构化的布局为程序添加一行。在此布局中,在组件上包含0前缀,并更新小时以使用12小时格式:

...

func main() {
    theTime := time.Date(2021, 8, 15, 14, 30, 45, 100, time.Local)
    fmt.Println("The time is", theTime)

    fmt.Println(theTime.Format("2006-1-2 15:4:5"))
    fmt.Println(theTime.Format("2006-01-02 03:04:05 pm"))
}

保存代码后,使用go-run再次运行程序:

go run main.go

输出如下:

Output
The time is 2021-08-15 14:30:45.0000001 -0500 CDT
2021-8-15 14:30:45
2021-08-15 02:30:45 pm

您将看到,通过在布局字符串中的数字添加0前缀,新输出中月份的8将变为08,以匹配布局。现在采用12小时格式的小时也有自己的0前缀。不过,最终,您在输出中看到的内容与您在代码中看到的格式相同,因此如果需要,调整格式更容易。

很多时候,格式化的日期是要由其他程序解释的,每次您想使用它们时,重新创建这些格式可能会成为负担。在某些情况下,您可以使用预定义的格式。

使用预定义格式

有许多常用的日期格式,例如日志消息的时间戳,每次您想使用时重新创建这些格式可能会很麻烦。对于其中一些情况,时间包包括可以使用的预定义格式。

可用和经常使用的格式之一是RFC 3339中定义的格式。RFC是用于定义互联网标准如何工作的文档,然后其他RFC可以相互建立。例如,有一个RFC定义了HTTP的工作方式(RFC 2616),其他一些RFC基于此进一步定义HTTP。因此,在RFC 3339的情况下,RFC定义了一种用于互联网上时间戳的标准格式。这种格式是众所周知的,并且在互联网上得到了很好的支持,因此在其他地方看到它的可能性很高。

时间包中的每个预定义时间格式都由一个常量字符串表示,该字符串以它们表示的格式命名。RFC 3339格式恰好有两种可用格式,一种称为时间。RFC3339和另一个名为time.RFC3339Nano。格式之间的区别在于时间。RFC3339Nano版本包含纳秒格式。

现在,打开主管道。再次打开文件并更新程序以使用时间。RFC3339Nano输出格式:

...

func main() {
    theTime := time.Date(2021, 8, 15, 14, 30, 45, 100, time.Local)
    fmt.Println("The time is", theTime)
    
    fmt.Println(theTime.Format(time.RFC3339Nano))
}

由于预定义的格式是具有所需格式的字符串值,您只需将通常使用的格式替换为其中一种格式即可。

要查看输出,请再次运行程序:

go run main.go

输出如下:

Output
The time is 2021-08-15 14:30:45.0000001 -0500 CDT
2021-08-15T14:30:45.0000001-05:00

如果需要将时间值保存为字符串,RFC3339格式很好用。它可以被许多其他编程语言和应用程序读取,并且与灵活的字符串格式的日期和时间一样紧凑。

在本节中,您更新了程序以使用Format方法打印日期和时间。使用这种灵活的布局还允许您的代码看起来与最终输出类似。最后,您使用一个预定义的布局字符串,以支持的格式打印出日期和时间。在下一节中,您将更新程序以将相同的字符串值转换回时间。您可以使用的时间值。

解析字符串中的日期和时间

通常在开发应用程序时,您会遇到表示为字符串值的日期,需要以某种方式进行解释。有时,您需要知道值的日期部分,有时您可能需要知道时间部分,而有时您可能会需要整个值。除了使用Format方法从时间创建字符串值之外。时间值,Go-Time包提供了一个时间。解析函数将字符串转换为时间。时间值。时间。Parse函数的工作方式类似于Format方法,因为它采用预期的日期和时间布局以及字符串值作为参数。

现在,打开总管。去你的程序中的文件并更新它以使用时间。Parse函数将timeString解析为时间。时间变量:

...

func main() {
    timeString := "2021-08-15 02:30:45"
    theTime, err := time.Parse("2006-01-02 03:04:05", timeString)
    if err != nil {
        fmt.Println("Could not parse time:", err)
    }
    fmt.Println("The time is", theTime)
    
    fmt.Println(theTime.Format(time.RFC3339Nano))
}

与Format方法不同,时间。如果传入的字符串值与作为第一个参数提供的布局不匹配,Parse方法还会返回一个潜在的错误值。如果你看一下所使用的布局,你会发现布局是给时间的。Parse使用Format方法中使用的相同的1表示月,2表示月日等。

保存更新后,可以使用go run运行更新的程序:

go run main.go

输出如下:

Output
The time is 2021-08-15 02:30:45 +0000 UTC
2021-08-15T02:30:45Z

在这个输出中有一些事情需要注意。一个是从timeString解析的时区使用默认时区,即+0偏移量,称为协调世界时(UTC)。由于时间值和布局都不包括时区,因此时间。解析函数不知道要与哪个时区关联。如果您在某个时候需要它,那么时间包中确实包含了时间。ParseInLocation函数,以便您可以提供要使用的位置。另一个需要注意的部分是RFC 3339输出。输出正在使用时间。RFC3339Nano布局,但输出不包括任何纳秒。这是因为时间。Parse函数不解析任何纳秒,因此该值被设置为默认值0。当纳秒为0时,时间。RFC3339Nano格式不会在输出中包含纳秒。

时间。解析字符串值时,Parse方法还可以使用时间包中提供的任何预定义时间布局。要在实践中看到这一点,请打开主管道。go文件并更新timeString值以匹配time的输出。RFC3339Nano更早,并更新时间。分析要匹配的参数:

...

func main() {
    timeString := "2021-08-15T14:30:45.0000001-05:00"
    theTime, err := time.Parse(time.RFC3339Nano, timeString)
    if err != nil {
        fmt.Println("Could not parse time:", err)
    }
    fmt.Println("The time is", theTime)
    
    fmt.Println(theTime.Format(time.RFC3339Nano))
}

更新代码后,可以保存程序并使用go-run再次运行:

go run main.go

输出如下:

Output
The time is 2021-08-15 14:30:45.0000001 -0500 CDT
2021-08-15T14:30:45.0000001-05:00

这一次,Format方法的输出显示了time.Parse能够解析时区和timeString中的纳秒。

在本节中,您使用time.Parse函数解析任意格式的日期和时间字符串值以及预定义的布局。不过,到目前为止,您还没有与您所看到的各种时区进行交互。Go为时间提供的另一组功能。时间类型是在不同时区之间转换的能力,您将在下一节中看到。

使用时区

当与世界各地的用户开发应用程序时,甚至只跨几个时区开发应用程序,通常的做法是使用协调世界时(UTC)存储日期和时间,然后在需要时转换为用户的本地时间。这允许数据以一致的格式存储,并使它们之间的计算更容易,因为只有在向用户显示日期和时间时才需要转换。

在本教程的前面部分中,您创建了一个程序,该程序主要基于本地时区的时间。为了节省时间。时间值为UTC,您首先需要将其转换为UTC。您将使用UTC方法执行此操作,该方法将返回您调用它的时间的副本,但使用UTC。

注意:此部分在计算机的本地时区和UTC之间转换时间。如果您使用的计算机将本地时区设置为与UTC匹配的时区,您会注意到在UTC和UTC之间再次转换不会显示时间差异。

现在,打开main.go文件更新程序,在time上使用UTC方法返回UTC版本的时间:

...

func main() {
    theTime := time.Date(2021, 8, 15, 14, 30, 45, 100, time.Local)
    fmt.Println("The time is", theTime)
    fmt.Println(theTime.Format(time.RFC3339Nano))
    
    utcTime := theTime.UTC()
    fmt.Println("The UTC time is", utcTime)
    fmt.Println(utcTime.Format(time.RFC3339Nano))
}

这一次,您的程序将时间创建为时间。本地时区中的时间值,以两种不同的格式打印出来,然后使用UTC方法将该时间从本地时间转换为UTC时间。

要查看程序的输出,可以使用go-run运行:

go run main.go

输出如下:

Output
The time is 2021-08-15 14:30:45.0000001 -0500 CDT
2021-08-15T14:30:45.0000001-05:00
The UTC time is 2021-08-15 19:30:45.0000001 +0000 UTC
2021-08-15T19:30:45.0000001Z

您的输出将因当地时区而异,但在上面的输出中,您将看到第一次打印出来的时间是CDT(北美中部夏时制),它距离UTC为-5小时。调用UTC方法并打印UTC时间后,您可以看到时间中的小时从14变为19,因为将时间转换为UTC增加了五个小时。

还可以使用时间上的local方法将UTC时间转换回本地时间。时间也一样。打开主电源。再次转到文件并更新它,以在utcTime上添加对Local方法的调用,将其转换回本地时区:

...

func main() {
    theTime := time.Date(2021, 8, 15, 14, 30, 45, 100, time.Local)
    fmt.Println("The time is", theTime)
    fmt.Println(theTime.Format(time.RFC3339Nano))
    
    utcTime := theTime.UTC()
    fmt.Println("The UTC time is", utcTime)
    fmt.Println(utcTime.Format(time.RFC3339Nano))

    localTime := utcTime.Local()
    fmt.Println("The Local time is", localTime)
    fmt.Println(localTime.Format(time.RFC3339Nano))
}

保存文件后,使用go-run运行程序:

go run main.go

输出如下:

Output
The time is 2021-08-15 14:30:45.0000001 -0500 CDT
2021-08-15T14:30:45.0000001-05:00
The UTC time is 2021-08-15 19:30:45.0000001 +0000 UTC
2021-08-15T19:30:45.0000001Z
The Local time is 2021-08-15 14:30:45.0000001 -0500 CDT
2021-08-15T14:30:45.0000001-05:00

您将看到UTC时间已转换回您的本地时区。在上面的输出中,UTC转换回CDT意味着从UTC中减去了五个小时,将小时从19更改为14。

在本节中,您更新了程序,以使用UTC方法在本地时区和标准UTC时区之间转换日期和时间,然后再次使用本地方法进行转换。

一旦您有了可用的日期和时间值,Go-time软件包提供了许多其他功能,这些功能可以在您的应用程序中使用。这些特征之一是确定给定时间是在另一时间之前还是之后。

比较两个时间

由于在比较两个日期时需要考虑所有变量,因此有时很难将两个日期进行比较。例如,需要考虑时区,或者月份之间的天数不同。时间包提供了一些方法使这变得更容易。

时间包提供了两种方法来简化这些比较:在time.time类型上可用的Before和After方法。这些方法都接受一个时间值,并根据调用它们的时间是在提供的时间之前还是之后返回true或false。

要查看这些函数的运行示例,请打开main.go文件并将其更新为包含两个不同的日期,然后使用Before和After比较这些日期以查看输出:

...

func main() {
    firstTime := time.Date(2021, 8, 15, 14, 30, 45, 100, time.UTC)
    fmt.Println("The first time is", firstTime)

    secondTime := time.Date(2021, 12, 25, 16, 40, 55, 200, time.UTC)
    fmt.Println("The second time is", secondTime)

    fmt.Println("First time before second?", firstTime.Before(secondTime))
    fmt.Println("First time after second?", firstTime.After(secondTime))

    fmt.Println("Second time before first?", secondTime.Before(firstTime))
    fmt.Println("Second time after first?", secondTime.After(firstTime))
}

更新文件后,保存文件并使用go-run运行:

go run main.go

输出如下:

Output
The first time is 2021-08-15 14:30:45.0000001 +0000 UTC
The second time is 2021-12-25 16:40:55.0000002 +0000 UTC
First time before second? true
First time after second? false
Second time before first? false
Second time after first? true

由于代码使用UTC时区中的显式日期,因此您的输出应该与上面的输出匹配。你会看到,当第一次使用Before方法并提供第二次比较时,这意味着2021 08-15是在2021 12-25之前。当使用firstTime的After方法并提供secondTime时,它说2021 08-15在2021 12-25之后是错误的。更改在secondTime调用方法的顺序会显示相反的结果,正如预期的那样。

用时间包比较两个日期和时间的另一种方法是Sub方法。Sub方法将从一个日期减去另一个日期,并使用新类型time.Duration返回一个值。不像以前。时间值,表示时间的绝对点。持续时间值表示时间差。例如,“在一小时内”将是一个持续时间,因为它根据一天中的当前时间表示不同的时间,但“在中午”表示特定的绝对时间。围棋利用时间。Duration类型有很多地方,比如您想定义函数在返回错误之前应该等待多长时间,或者在这里,您需要知道一个时间和另一个时间之间的间隔。

现在,更新你的主页。go file对firstTime和secondTime值使用Sub方法,并打印结果:

...

func main() {
    firstTime := time.Date(2021, 8, 15, 14, 30, 45, 100, time.UTC)
    fmt.Println("The first time is", firstTime)

    secondTime := time.Date(2021, 12, 25, 16, 40, 55, 200, time.UTC)
    fmt.Println("The second time is", secondTime)

    fmt.Println("Duration between first and second time is", firstTime.Sub(secondTime))
    fmt.Println("Duration between second and first time is", secondTime.Sub(firstTime))

保存文件,然后使用go run运行:

go run main.go

输出如下:

Output
The first time is 2021-08-15 14:30:45.0000001 +0000 UTC
The second time is 2021-12-25 16:40:55.0000002 +0000 UTC
Duration between first and second time is -3170h10m10.0000001s
Duration between second and first time is 3170h10m10.0000001s

上面的输出表示两个日期之间有3170小时、10分钟、10秒和100纳秒,关于输出有一些需要注意的事情。第一个是第一次和第二次之间的持续时间是负值。这表示第二次是在第一次之后,类似于从0中减去5得到-5。第二件要注意的是,持续时间的最大度量单位是一小时,因此它不会将其分解为天或月。由于一个月的天数不一致,在夏时制切换期间,“天”可能有不同的含义,因此小时是最准确的测量值,不会出现波动。

在本节中,您使用三种不同的方法更新了程序以进行两次比较。首先,您使用Before和After方法来确定一个时间是在另一个时间之前还是之后,然后使用Sub来查看两个时间之间的时间间隔。获取两次之间的持续时间并不是时间包使用时间的唯一方法。但持续时间。您还可以使用它添加或删除时间。时间值,您将在下一节中看到。

加减时间

在编写应用程序时,使用日期和时间的一个常见操作是根据另一个时间确定过去或将来的时间。它可以用于功能,例如确定下一个订阅何时更新,或者检查某个值后是否已经过了一段时间。不管怎样,Go-time包都提供了一种处理方法。然而,要根据你已经知道的日期找到另一个日期,你需要能够定义自己的时间。持续时间值。

创造时间。持续时间值类似于你在纸上写持续时间的方式,只是用乘法表示时间单位。例如,创建时间。持续时间表示一小时,您可以使用时间定义它。小时值乘以所需时间的小时数。代表时间:

oneHour := 1 * time.Hour
twoHours := 2 * time.Hour
tenHours := 10 * time.Hour

声明较小的时间单位以类似的方式处理,除了使用时间。分钟,时间。第二,依此类推:

tenMinutes := 10 * time.Minute
fiveSeconds := 5 * time.Second

也可以将一个持续时间添加到另一个持续,以获得持续时间的总和。要查看此操作,请打开主管道。转到文件并更新它,以声明一个toAdd持续时间变量,并向其添加不同的持续时间:

...

func main() {
    toAdd := 1 * time.Hour
    fmt.Println("1:", toAdd)

    toAdd += 1 * time.Minute
    fmt.Println("2:", toAdd)

    toAdd += 1 * time.Second
    fmt.Println("3:", toAdd)
}

更新完成后,保存文件并使用go-run运行程序:

go run main.go

输出如下:

Output
1: 1h0m0s
2: 1h1m0s
3: 1h1m1s

当您查看输出时,您会发现打印的第一个持续时间是一小时,对应于1*时间。代码中的小时。接下来,您添加了1*时间。分钟到toAdd值,它显示为一小时一分钟的值。最后,您添加了1*时间。其次是toAdd,这导致了时间。持续时间值为一小时、一分钟和一秒。

也可以在一个语句中将持续时间相加,或从另一个语句中减去持续时间:

oneHourOneMinute := 1 * time.Hour + 1 * time.Minute
tenMinutes := 1 * time.Hour - 50 * time.Minute

接下来,打开主管道。去文件并更新你的程序,用这样的组合从toAdd中减去一分一秒:

...

func main() {
    
    ...
    
    toAdd += 1 * time.Second
    fmt.Println("3:", toAdd)
    
    toAdd -= 1*time.Minute + 1*time.Second
    fmt.Println("4:", toAdd)
}

保存代码后,可以使用go-run运行程序:

go运行main.go

输出如下:

Output
1: 1h0m0s
2: 1h1m0s
3: 1h1m1s
4: 1h0m0s

添加到输出中的新的第四行显示了您所包含的用于减去1*时间之和的新代码。分钟和1*时间。第二次工作正常,导致原来的一小时值再次出现。

将这些持续时间与时间的Add方法配对使用。时间类型允许您获取已有的时间值,并确定该时间之前或之后某个其他任意点的时间。要查看此运行的示例,请打开主视图。转到文件并更新,以将toAdd值设置为24小时或24*time.Hour。然后,每次使用Add方法。时间值,查看该点后24小时的时间:

...

func main() {
    theTime := time.Date(2021, 8, 15, 14, 30, 45, 100, time.UTC)
    fmt.Println("The time is", theTime)

    toAdd := 24 * time.Hour
    fmt.Println("Adding", toAdd)

    newTime := theTime.Add(toAdd)
    fmt.Println("The new time is", newTime)
}

保存文件后,使用go-run运行程序:

go run main.go

输出如下:

Output
The time is 2021-08-15 14:30:45.0000001 +0000 UTC
Adding 24h0m0s
The new time is 2021-08-16 14:30:45.0000001 +0000 UTC

看看输出,你会发现在2021 08月15日之前增加24小时,结果是新的日期为2021 08月16日。

要减去时间,还可以使用Add方法,这有点违反直觉。由于Sub方法用于计算两个日期之间的时间差,因此可以使用负值的Add从time.time值中减去时间。

再次,要在程序中看到这一点,请打开main.go文件并进行更新,将24小时toAdd值更改为负值:

...

func main() {
    theTime := time.Date(2021, 8, 15, 14, 30, 45, 100, time.UTC)
    fmt.Println("The time is", theTime)

    toAdd := -24 * time.Hour
    fmt.Println("Adding", toAdd)

    newTime := theTime.Add(toAdd)
    fmt.Println("The new time is", newTime)
}

保存文件后,使用go-run再次运行程序:

go run main.go

输出如下:

Output
The time is 2021-08-15 14:30:45.0000001 +0000 UTC
Adding -24h0m0s
The new time is 2021-08-14 14:30:45.0000001 +0000 UTC

这一次,在输出中您将看到,新日期不是在原始时间上添加24小时,而是在原始时间之前24小时。

在本节中,您使用了时间。小时,时间。分钟和时间。第二,创造时间。不同程度的持续时间值。你也利用了时间。使用Add方法获取新时间的持续时间值。原始值之前和之后的时间值。通过组合时间。现在,使用Add方法和Before或After方法,您可以访问应用程序的强大日期和时间功能。

结论

在本教程中,您使用了时间。现在找回时间。计算机上当前本地时间的时间值,然后使用年、月、小时和其他方法访问有关该时间的特定信息。然后,使用Format方法使用自定义格式和预定义格式打印时间。接下来,你利用了时间。解析函数,用于解释包含时间的字符串值,并从中提取时间值。获得时间值后,使用UTC和Local方法转换UTC和本地时区之间的时间。之后,使用Sub方法获取两个不同时间之间的持续时间,然后使用Add方法查找相对于不同时间值的时间。

使用本教程中描述的各种函数和方法将对您的应用程序有很大帮助,但如果您感兴趣,go-time包还包括许多其他功能。

文章链接