Go 语言 time 包常用用法笔记
amc · · 2120 次点击 · · 开始浏览Go 的时间操作基本上都用 time 包,比 C 的 time 函数和 timeval 等 struct 好用多了。不过 time 包还是有不少用法和其他语言不同的,所以有必要写个笔记记录一下。
本文链接:https://segmentfault.com/a/1190000020944345,首次发布于云+社区
*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 | |
如果需要自定义的星期几名,需要搭配 time 的 Weekday()函数,返回 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。
有疑问加站长微信联系(非本文作者)
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
关注微信- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码` - 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传
收入到我管理的专栏 新建专栏
Go 的时间操作基本上都用 time 包,比 C 的 time 函数和 timeval 等 struct 好用多了。不过 time 包还是有不少用法和其他语言不同的,所以有必要写个笔记记录一下。
本文链接:https://segmentfault.com/a/1190000020944345,首次发布于云+社区
*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 | |
如果需要自定义的星期几名,需要搭配 time 的 Weekday()函数,返回 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日