专栏首页后台全栈之路Go 语言 time 包常用用法笔记
原创

Go 语言 time 包常用用法笔记

Go 的时间操作基本上都用 time 包,比 C 的 time 函数和 timeval 等 struct 好用多了。不过 time 包还是有不少用法和其他语言不同的,所以有必要写个笔记记录一下。

本文地址:[https://cloud.tencent.com/developer/article/1456484](https://cloud.tencent.com/developer/article/1456484)

*time.Location 类型

和其他文章不同的是,本文我从时区讲起。在 Go 中,表示时区的类型是 type Location struct{...},代码中使用 *time.Location 对象。

对于不严格的场景而言,可以获取服务器所处的时区。但是本文不建议这个方法。因为一台服务器服务的时区是事先可知的,或者说是需要对接的时区信息也是已知的(比如对接微信,那么时间肯定是东八区,而不是 UTC 时间)。获得东八区时区的代码如下:

loc, _ := time.LoadLocation("Asia/Shanghai")

之后这个 loc 可以作为常量使用。是否能够拿到时区,取决于机器本地的 zoneinfo 文件。后文也将使用这个 loc 作为全局变量。

也可以自定义一个时区名称,比如我们人工添加一个巴西利亚时间:

brazil := time.FixedZone("Brazil/Brasilia", -3*60*60)

这里我们同时要知道一个很重要的概念,就是在 *Location 的加持下,一个 Time 类型本身是同时记录着 UTC 时间和本地时间的,这就使得一个 Go 时间类型不会因为时区而出现歧义,比如你可以用一个东八区的 Time 和西八区的 Time 随意进行运算也不会出错。这一特性使得时间类型变得极为实用。

time.Time 类型

Time 创建及与 string 类型互转

最基本的创建时间类型的接口:

t := time.Now()

此外,很多资料会跟你说采用 Local() 函数获得本地时间,但基于前述理由,我建议固定指定 location:

t := time.Now().In(loc)

 其他的几个创建时间的函数:

  • t := time.Date(y, m, d, h, min, s, nsec, loc):用从年到纳秒,以及时区信息,创建一个时间。参数均为整型
  • t := time.Unix(s, nsec):使用 Unix UTC 时间戳来创建时间

如果将 time 类型转换成字符串,采用以下函数:

s := t.Format("2006-01-02 15:04:05.000")		// 输出如:"2019-07-03 22:10:23.437"

通过已知格式的字符串解析时间的函数为:

t, err := time.ParseInLocation("2006-01-02 15:04:05", s, loc)

略微了解过 Go time 的人都知道,Go 时间格式化采用的并不是传统的 YYYY-MM-DD hh:mm:ss 格式。这里有一份对应表,便于组装字符串时查阅——以时间 1609-08-12 19:02:35 PM +03:00 Aug Wed PDT 为例,这个时间的含义是:1609年9月12日,北美太平洋地区时间下午7:02:35,应用以下格式的输出举例:

类型

格式符

输出举例

说明

2006

1609

06

09

01

08

1

8

Jan

Aug

January

August

02

02

2

2

周几

Mon

Wed

注意,格式符里没有数字化的周几信息,需要自己拼。参见后文

Monday

Wednesday

小时

03

07

12小时制,01~12,12点表示正午

3

7

12小时制,1~12,12点表示正午

15

19

24小时制,0~23,永远都是两位数字,不足2位补0,如早上7点:"07"

分钟

04

02

4

2

05

35

5

35

上 / 下午

PM

PM

小数点后秒数

.000

.123

.000000

.123456

.000000000

.123456789

实际上,可以是小于9位的任意位数的0,只要是以 . 打头

时区偏移

-0700

+0300

-07:00

+03:00

Z0700

+0300

Z07:00

+03:00

时区名

MST

PDT

如果需要自定义的星期几名,需要搭配 timeWeekday()函数,返回 Weekday 类型(等同于 int 类型),以 0 代表星期天。如下:

wday := []string{"日", "一", "二", "三", "四", "五", "六"}
s := fmt.Sprintf(t.Format("2006-01-02 15:04:05 星期%s"), wday[t.Weekday()])
fmt.Println(s)		// 1609-08-12 19:02:35 星期三

时间比较

time.Time 提供了一个 IsZero() 函数来判断时间类型是否为空的状态。空时间所指代的时间是 UTC 时间公元元年 00:00:00,这是 t := time.Time{} 所生成的时间。

主要的比较函数如下:

  • func (t Time) IsZero() bool
  • func (t Time) After(u Time) bool:判断是否在另一个时间之后
  • func (t Time) Before(u Time) bool:判断是否在另一个时间之前
  • func (t Time) Equal(u Time) bool:判断两个时间是否相等
  • func (t Time) Sub(u Time) Duration:计算两个时间之间的差。Duration 类型会在下一小节说明
    • 注意这个和 Add() 函数的使用场景是完全不同的,不得不吐槽一下两者的命名……

时间运算

  • func (t Time) Add(d Duration):加上一个时间段,返回一个新的时间。d 也可以是负的时间
  • func (t Time) AddDate(年, 月, 日):加上一个日期,获返回一个新的时间。各参数均为整型,可以是负数
    • 比如 t.AddDate(0, 1, -1) 表示加上一个月之后再减一天
  • func Since(u Time) Duration:表示当前时间与一个过去的时间的差;如果被比较的时间是将来时间的话,那么返回负的 Duration
    • 等价于 time.Now().Sub(t)
  • func Until(u Time) Duration:这是Since` 的反逻辑
    • 等价于 t.Sub(time.Now())

获取时间的基本函数

以下函数可以获取时间的基本信息,返回均为整型,很好理解:

  • t.Year()
  • t.Month()
  • t.Day()
  • t.Weekday():返回以星期天为 0 的星期几数值
  • t.YearDay():返回处于每一年的第几天
  • t.Hour()
  • t.Minute()
  • t.Second()
  • t.Nanosecond():时间的毫秒部分,int 类型
  • t.Unix():返回 Unix UTX 时间戳,int64 类型

Duration 类型

Duration 类型的作用是用来表示两个时间点之间的时间段。Duration 实际上是 int64 类型,单位是纳秒。但在实际编码中,基本上不会直接赋值一个数字,而是用 time 提供的常量,如:

tenSecs := 10 * time.Second
twoHours := 2 * time.Hour

其他常量还有:

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

此外,Duration 类型还有下面的实用的方法:

  • func (d Duration) Round(m Duration) Duration:表示按照 m 给定的单位,返回四舍五入
  • func (d Duration) Truncate(m Duration) Duration:表示按照 m 给定的单位,返回舍尾数计算
  • func (d Duration) String() string:给出几小时几分钟几秒的字符串格式,非常适合打日志
  • Hours(), Minutes(), Seconds():返回 float64 格式,也就是小数形式的小时 / 分钟 / 秒数
  • Nanoseconds():返回 int64 类型的纳秒数

参考资料

本文章采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。

原作者: amc,欢迎转载,但请注明出处。

原文标题:Go 语言 time 包常用用法笔记

发布日期:2017-07-03

原文链接:https://cloud.tencent.com/developer/article/1456484

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

登录 后参与评论
0 条评论

相关文章

  • Go之time包用法

    time包提供了时间的显示和测量用的函数。日历的计算采用的是公历。 time 类型

    孤烟
  • Go之time包用法

    孤烟
  • Go语言:map使用笔记

    Go 的 map 是 hash map; C++ 的 map 是 tree (主流实现是红黑树); C++ 的 hash map 是unordered_ma...

    linjinhe
  • Go常量 【Go语言圣经笔记】

    常量表达式的值在编译期计算,而不是在运行期。每种常量的潜在类型都是基础类型:boolean、string或数值型。

    Steve Wang
  • Go语言实战笔记(一)| Go包管理

    这本是In Action系列的书籍,这个系列做研发的都知道,在研发届评价很多,很多新的技术、语言等都会有一本实战的书籍。既然是实战,那么这本书假设了他的读者有了...

    飞雪无情
  • 作用域 【Go语言圣经笔记】

    一个声明语句将程序中的实体和一个名字关联,比如一个函数或一个变量。声明语句的作用域是指源代码中可以有效使用这个名字的范围。

    Steve Wang
  • Go语言常用命令

    在 GOPATH/bin 目录下构建 GOPATH/src 目录下的 XXX 文件夹所包含的项目:

    hotarugali
  • Go语言实战笔记(八)| Go 函数方法

    在Go语言中,函数和方法不太一样,有明确的概念区分。其他语言中,比如Java,一般来说,函数就是方法,方法就是函数,但是在Go语言中,函数是指不属于任何结构体、...

    飞雪无情
  • 《Go语言程序设计》读书笔记(七) 包

    Go语言有超过100个的标准包(可以用 go list std|wc-l命令查看标准包的具体数目),标准库为大多数的程序提供了必要的基础构件。在Go的社区,有很...

    KevinYan
  • Go语言_iota用法

    在每一个const关键字出现时,被重置为0,然后再下一个const出现之前,每出现一次iota,其所代表的数字会自动增加1。

    Zoctopus
  • Go语言核心36讲(Go语言实战与应用九)--学习笔记

    我们在前几次讲的互斥锁、条件变量和原子操作都是最基本重要的同步工具。在 Go 语言中,除了通道之外,它们也算是最为常用的并发安全工具了。

    郑子铭
  • Go语言核心36讲(Go语言实战与应用八)--学习笔记

    我们接着上一篇文章的内容继续聊,上一篇我们提到了,sync/atomic包中的函数可以做的原子操作有:加法(add)、比较并交换(compare and swa...

    郑子铭
  • Go语言核心36讲(Go语言实战与应用一)--学习笔记

    在接下来的日子里,我将带你去学习在 Go 语言编程进阶的道路上,必须掌握的附加知识,比如:Go 程序测试、程序监测,以及 Go 语言标准库中各种常用代码包的正确...

    郑子铭
  • Go语言核心36讲(Go语言实战与应用七)--学习笔记

    互斥锁是一个很有用的同步工具,它可以保证每一时刻进入临界区的 goroutine 只有一个。读写锁对共享资源的写操作和读操作则区别看待,并消除了读操作之间的互斥...

    郑子铭
  • Go语言核心36讲(Go语言实战与应用五)--学习笔记

    我们常常会把条件变量这个同步工具拿来与互斥锁一起讨论。实际上,条件变量是基于互斥锁的,它必须有互斥锁的支撑才能发挥作用。

    郑子铭
  • Go语言核心36讲(Go语言实战与应用六)--学习笔记

    这些问题我在面试的时候也经常问。你需要对这个Wait方法的内部机制有所了解才能回答上来。

    郑子铭
  • Go语言核心36讲(Go语言实战与应用三)--学习笔记

    在本篇文章,我会继续为你讲解更多更高级的测试方法。这会涉及testing包中更多的 API、go test命令支持的,更多标记更加复杂的测试结果,以及测试覆盖度...

    郑子铭
  • Go语言核心36讲(Go语言实战与应用四)--学习笔记

    从本篇文章开始,我们将一起探讨 Go 语言自带标准库中一些比较核心的代码包。这会涉及这些代码包的标准用法、使用禁忌、背后原理以及周边的知识。

    郑子铭
  • Go语言核心36讲(Go语言实战与应用十)--学习笔记

    我们在上篇文章中讲到了sync.WaitGroup类型:一个可以帮我们实现一对多 goroutine 协作流程的同步工具。

    郑子铭

扫码关注云+社区

领取腾讯云代金券