分享
  1. 首页
  2. 文章

golang time 格式详解

银冰雪千载 · · 19608 次点击 · · 开始浏览
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

神奇时刻:2006年01月02日 15:04:05

1 官方文档

time package(需科学上网查看):https://golang.org/pkg/time/

2 自定义时间格式

在看代码之前,先问一个关键问题:你懂 2006年01月02日 15:04:05 么?不懂还是看代码吧!

package main
import (
 "fmt"
 "time"
)
func main() {
 // 使用系统默认格式打印当前时间
 t1 := time.Now();
 fmt.Println("t1:", t1)
 // 自定义格式,相当于Java中的时间格式:yyyy-MM-dd HH:mm:ss
 t2 := t1.Format("2006年01月02日 15:04:05")
 fmt.Println("t2:", t2)
 // 换个时间定义格式不行么?答案:不行
 t3 := t1.Format("2018年10月01日 15:18:00")
 fmt.Println("t3:", t3)
 // 自定义解析时间字符串格式
 t4, _ := time.Parse("2006年01月02日 15:04:05", "2018年10月01日 14:51:00")
 fmt.Println("t4:", t4)
}

示例输出:

t1: 2018年10月01日 15:35:54.7057525 +0800 CST m=+0.006020701
t2: 2018年10月01日 15:35:54
t3: 1108-100-10 15:108:00
t4: 2018年10月01日 14:51:00 +0000 UTC

简而言之,其他常规语言使用字母 "ymd" 编写时间格式,而 golang 使用固定的时刻 "2006年01月02日 15:04:05" 编写时间格式。 优点就是所见即所得,立刻看到效果,缺点就是,你要记住这个时刻,这是目前为止遇到的第一个挑战。至于为什么是这个时时刻?它有什么意义?我不知道。

标准库内置定义的时间格式常量如下:

const (
 ANSIC = "Mon Jan _2 15:04:05 2006"
 UnixDate = "Mon Jan _2 15:04:05 MST 2006"
 RubyDate = "Mon Jan 02 15:04:05 -0700 2006"
 RFC822 = "02 Jan 06 15:04 MST"
 RFC822Z = "02 Jan 06 15:04 -0700" // RFC822 with numeric zone
 RFC850 = "Monday, 02-Jan-06 15:04:05 MST"
 RFC1123 = "2006年1月02日 15:04:05 MST"
 RFC1123Z = "2006年1月02日 15:04:05 -0700" // RFC1123 with numeric zone
 RFC3339 = "2006年01月02日T15:04:05Z07:00"
 RFC3339Nano = "2006年01月02日T15:04:05.999999999Z07:00"
 Kitchen = "3:04PM"
 // Handy time stamps.
 Stamp = "Jan _2 15:04:05"
 StampMilli = "Jan _2 15:04:05.000"
 StampMicro = "Jan _2 15:04:05.000000"
 StampNano = "Jan _2 15:04:05.000000000"
)

看了之后,叹了口气,为啥常用的 "2006年01月02日 15:04:05" 时间格式都没有,看来以后还得自食其力。

3 时区

由于世界各国家与地区经度不同,地方时也有所不同,因此会划分为不同的时区。正式的时区划分,其中包括24个时区,每一时区由一个英文字母表示。每隔经度15°划分一个时区。

3.1 如何计算区时?

计算的区时=已知区时-(已知区时的时区-要计算区时的时区),(注:东时区为正,西时区为负)。

下面举例加以说明:

例1:已知东京(东九区)时间为5月1日12:00,求北京(东八区)的区时?

北京时间=12:00-(9-8)=11:00(即北京时间为5月1日11:00)。

3.2 UTC

UTC 不属于任意时区 。协调世界时,又称世界统一时间,世界标准时间,国际协调时间,简称 UTC。

3.3 时区解析

下面是几个解析时区的例子,这个问题困了我一周。代码如下:

// 考虑时区:下面对么?答案:不对
t5, _ := time.Parse("2006年01月02日T15:04:05Z07:00", "2018年10月01日T16:27:00Z08:00")
fmt.Println("t5:", t5) // 输出:t5: 0001年01月01日 00:00:00 +0000 UTC
// 考虑时区:上面正确的格式是把 "Z" 替换成 "+" 或者 "-",分别代表正负时区。
t6, _ := time.Parse("2006年01月02日T15:04:05Z07:00", "2018年10月01日T16:27:00+08:00")
fmt.Println("t6:", t6) // 输出:t6: 2018年10月01日 16:27:00 +0800 CST
// 考虑时区:如果解析的格式不带时区,将由 time.ParseInLocation 第三个参数决定
t7, _ := time.ParseInLocation("2006年01月02日T15:04:05", "2018年10月01日T16:27:00", time.Local)
fmt.Println("t7:", t7) // 输出:t7: 2018年10月01日 16:27:00 +0800 CST
// 考虑时区:使用 UTC
t8, _ := time.ParseInLocation("2006年01月02日T15:04:05", "2018年10月01日T16:27:00", time.UTC)
fmt.Println("t8:", t8) // 输出:t8: 2018年10月01日 16:27:00 +0000 UTC

官方例子代码如下:

// See the example for Time.Format for a thorough description of how
// to define the layout string to parse a time.Time value; Parse and
// Format use the same model to describe their input and output.
// longForm shows by example how the reference time would be represented in
// the desired layout.
const longForm = "Jan 2, 2006 at 3:04pm (MST)"
t, _ := time.Parse(longForm, "Feb 3, 2013 at 7:54pm (PST)")
fmt.Println(t)
// shortForm is another way the reference time would be represented
// in the desired layout; it has no time zone present.
// Note: without explicit zone, returns time in UTC.
const shortForm = "2006-Jan-02"
t, _ = time.Parse(shortForm, "2013-Feb-03")
fmt.Println(t)
// Some valid layouts are invalid time values, due to format specifiers
// such as _ for space padding and Z for zone information.
// For example the RFC3339 layout 2006年01月02日T15:04:05Z07:00
// contains both Z and a time zone offset in order to handle both valid options:
// 2006年01月02日T15:04:05Z
// 2006年01月02日T15:04:05+07:00
t, _ = time.Parse(time.RFC3339, "2006年01月02日T15:04:05Z")
fmt.Println(t)
t, _ = time.Parse(time.RFC3339, "2006年01月02日T15:04:05+07:00")
fmt.Println(t)
_, err := time.Parse(time.RFC3339, time.RFC3339)
fmt.Println("error", err) // Returns an error as the layout is not a valid time value

输出如下:

2013年02月03日 19:54:00 -0800 PST
2013年02月03日 00:00:00 +0000 UTC
2006年01月02日 15:04:05 +0000 UTC
2006年01月02日 15:04:05 +0700 +0700
error parsing time "2006年01月02日T15:04:05Z07:00": extra text: 07:00

官方解释很清楚,对于 time.RFC3339 (2006年01月02日T15:04:05Z07:00) 中的 Z , 包含单独的 "Z" 或者是包含正负号的时区偏移都是有效格式,例如:

  • 2006年01月02日T15:04:05Z
  • 2006年01月02日T15:04:05+07:00

更多关于 time.Parse 函数的详情可参考:官方文档 time.Parse 说明


有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:银冰雪千载

查看原文:golang time 格式详解

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

关注微信
19608 次点击 ∙ 1 赞
暂无回复
添加一条新回复 (您需要 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传

用户登录

没有账号?注册
(追記) (追記ここまで)

今日阅读排行

    加载中
(追記) (追記ここまで)

一周阅读排行

    加载中

关注我

  • 扫码关注领全套学习资料 关注微信公众号
  • 加入 QQ 群:
    • 192706294(已满)
    • 731990104(已满)
    • 798786647(已满)
    • 729884609(已满)
    • 977810755(已满)
    • 815126783(已满)
    • 812540095(已满)
    • 1006366459(已满)
    • 692541889

  • 关注微信公众号
  • 加入微信群:liuxiaoyan-s,备注入群
  • 也欢迎加入知识星球 Go粉丝们(免费)

给该专栏投稿 写篇新文章

每篇文章有总共有 5 次投稿机会

收入到我管理的专栏 新建专栏