go 时间格式风格详解

前端之家收集整理的这篇文章主要介绍了go 时间格式风格详解前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

一段代码

这里有一段代码 play 更能解说 layout. 可以看出,go 自动识别并转换 time 字符串是完全可能的.

time package@H_403_5@

go 的time package 提供了time.Format函数,用来对时间进行格式化输出

类似的还有time.Parse用来解析字符串类型的时间到time.Time。这是两个互逆的函数

问题是,go 采用的格式化 layout 和我们以往所用的任何经验都不同。以至于初次接触总是一头雾 水。

其实 go 提供的这个 layout 对算法的实现非常科学高效,而且很规律。下面我们详细分解下。

直接上个对应表@H_403_5@

前面是含义,后面是 go 的表示值,多种表示,逗号","分割

  • 月份 1,01,Jan,January
  • 日  2,02,_2
  • 时  3,03,15,PM,pm,AM,am
  • 分  4,04
  • 秒  5,05
  • 年  06,2006
  • 周几 Mon,Monday
  • 时区时差表示 -07,-0700,Z0700,Z07:00,-07:00,MST
  • 时区字母缩写 MST

您看出规律了么!哦是的,你发现了,这里面没有一个是重复的,所有的值表示都唯一对应一个时间部分。并且涵盖了很多格式组合。

比如小时的表示(原定义是下午3时,也就是15时)

  • 3 用12小时制表示,去掉前导0
  • 03 用12小时制表示,保留前导0
  • 15 用24小时制表示,保留前导0
  • 03pm 用24小时制am/pm表示上下午表示,保留前导0
  • 3pm 用24小时制am/pm表示上下午表示,去掉前导0

补充

2014-02-26日 在解析时 layout 中要用 pm 或 PM,分别对应数据中的 am/pm,AM/PM,大小写敏感. 如果 layout 有前导 0,那数据中就不能省略

又比如月份

  • 1 数字表示月份,去掉前导0
  • 01 数字表示月份,保留前导0
  • Jan 缩写单词表示月份
  • January 全单词表示月份

实例对应

真实时间:我的UTC时间是 2013年12月5日,我的本地时区是Asia/Shanghai

字符表示:  2013 12 5 CST

Go Layout: 2006 01 2 MST

真实时间:我的UTC时间是 2013年12月22点,我的本地时区是Asia/Shanghai

字符表示:  2013 12 22 CST

Go Layout: 2006 01 15 MST

而所有这些数字的顺序正好是1,2,4,5,6,7和一个时区

补充

2014-01-17日 发现上面的时间举例不准确,应该加上时分秒才能说明清楚时区的问题

下面示例时区问题

真实时间:我的本地时间是 2014-01-17 01:19:15,我的本地时区是 Asia/Shanghai

RFC3339格式:2006-01-02T15:04:05Z07:00

RFC3339输出:2014-01-17T01:19:15+08:00

自定义格式:2006-01-02 15:04:05 -07:00

自定义输出:2014-01-17 01:19:15 +08:00

自定义格式:2006-01-02 15:04:05 -07:00 MST

自定义输出:2014-01-17 01:19:15 +08:00 CST

UCT()输出:2014-01-16 17:19:15.9092754 +0000 UTC

注意看:UTC时间和本地时间和时区时差的差异

也就是说:

未经UTC()函数处理的时间输出表示的是本地时间带时区(如果是带时区的格式)

如果要计算 UTC 时间一定要记得使用UTC()函数后再进行其他操作.

MST是北美山区时区的英文缩写,Asia/Shanghai对应的时区缩写是CST.这个CST是从所在操作系统获取的,windows系统和别的不同,还做了特殊处理,具体比较复杂.感兴趣请自己分析zoneinfo_abbrs_windows.go.

注意缩写虽然是代表某个时区,但是由于缩写有重复的,所以无法计算时差 参见 时区缩写 靠缩写来判断时差是不可靠的

除了上面的时区缩写名称表示时区,时区还可以用

Z0700,Z070000,Z07:00:00

-0700,-070000,-07:00:00

前缀 "Z"和"-" 两种风格以时差表示时区.

其实还有一个秒的 repeated digits for fractional seconds 表示法

用的是 0和9,很少用,源代码里面是这样写的

<!-- lang: cpp -->
stdFracSecond0                          // ".0",".00",...,trailing zeros included
stdFracSecond9                          // ".9",".99",trailing zeros omitted

time.Parse 无时差时区layout@H_403_5@

代码输出

<!-- lang: cpp -->
time.Parse("2006-01-02 15:04:05","2014-01-17 03:06:54")
// 2014-01-17 03:06:54 +0000 UTC <nil>

如果layout未定义时差时区,那么时区是按UTC计算的. 缩写时区是不可靠的.

那些分界符@H_403_5@

除了那些值之外的都是分界符号,自然匹配了,直接举例子吧

字符表示:  2013-12 21 CST

Go Layout: 2006-01 15 MST

字符表示:  2013年12月21时 时区CST

Go Layout: 2006年01月15时 时区MST

好了,您是否感觉这个表示方法兼容度更好,适应性更强呢,更容易记忆呢。

公元前的时间问题@H_403_5@

公元前的时间年份是负值,time package输出没有问题,但是parser是不支持年份的负值的,不知道这算不算BUG.看官请自己注意.

提交了个 issues. 官方认为问题不严重,这是一种特殊场景,开发者可以特别处理下. 无需为此更改time package.

UTC时间 1月2日下午3时4分5秒 2006 年,本地时区-0700,还有999999999纳秒的零头@H_403_5@

猜你在找的Go相关文章