简介
不论什么时候,解决工夫总是让人头疼的一件事件。因为工夫格局太多样化了,再加上时区,夏令时,闰秒这些细枝末节解决起来更是艰难。所以在程序中,波及工夫的解决咱们个别借助于规范库或第三方提供的工夫库。明天要介绍的dateparse
专一于一个很小的工夫解决畛域——解析日期工夫格局的字符串。
疾速应用
本文代码应用 Go Modules。
创立目录并初始化:
$ mkdir dateparse && cd dateparse$ go mod init github.com/darjun/go-daily-lib/dateparse
装置dateparse
库:
$ go get -u github.com/araddon/dateparse
应用:
package mainimport ( "fmt" "log" "github.com/araddon/dateparse")func main() { t1, err := dateparse.ParseAny("3/1/2014") if err != nil { log.Fatal(err) } fmt.Println(t1.Format("2006-01-02 15:04:05")) t2, err := dateparse.ParseAny("mm/dd/yyyy") if err != nil { log.Fatal(err) } fmt.Println(t2.Format("2006-01-02 15:04:05"))}
ParseAny()
办法承受一个日期工夫字符串,解析该字符串,返回time.Time
类型的值。如果传入的字符串dateparse
库无奈辨认,则返回一个谬误。下面程序运行输入:
$ go run main.go2014-03-01 00:00:002021/06/24 14:52:39 Could not find format for "mm/dd/yyyy"exit status 1
须要留神,当咱们写出"3/1/2014"这个工夫的时候,能够解释为2014年3月1日,也能够解释为2014年1月3日。这就存在二义性,dateparse
默认采纳mm/dd/yyyy
这种格局,也就是2014年3月1日。咱们也能够应用ParseStrict()
函数让这种具备二义性的字符串解析失败:
func main() { t, err := dateparse.ParseStrict("3/1/2014") if err != nil { log.Fatal(err) } fmt.Println(t.Format("2006-01-02 15:04:05"))}
运行:
$ go run main.go2021/06/24 14:57:18 This date has ambiguous mm/dd vs dd/mm type formatexit status 1
格局
dateparse
反对丰盛的日期工夫格局,根本囊括了所有罕用的格局。它反对规范库time
中预约义的所有格局:
// src/time/format.goconst ( 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 = "Mon, 02 Jan 2006 15:04:05 MST" RFC1123Z = "Mon, 02 Jan 2006 15:04:05 -0700" // RFC1123 with numeric zone RFC3339 = "2006-01-02T15:04:05Z07:00" RFC3339Nano = "2006-01-02T15: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")
反对的残缺格局查看dateparse README。
时区
dateparse
反对在特定时区解析日期工夫字符串。咱们能够通过调用规范库的time.LoadLocation()
办法,传入时区标识字符串来取得时区对象。时区标识字符串是相似Asia/Shanghai
,America/Chicago
这样的格局,它示意一个具体的时区,前者上海,后者洛杉矶。调用dateparse.ParseIn()
办法传入时区对象,在指定时区中解析。time
包中还预约义了两个时区对象,time.Local
示意本地时区,time.UTC
示意 UTC 时区。时区的权威数据请看IANA。
func main() { tz1, _ := time.LoadLocation("America/Chicago") t1, _ := dateparse.ParseIn("2021-06-24 15:50:30", tz1) fmt.Println(t1.Local().Format("2006-01-02 15:04:05")) t2, _ := dateparse.ParseIn("2021-06-24 15:50:30", time.Local) fmt.Println(t2.Local().Format("2006-01-02 15:04:05"))}
运行:
$ go run main.go2021-06-25 04:50:302021-06-24 15:50:30
美国洛杉矶时区的"2021年6月24日 15时30分30秒"等于本地时区(北京工夫)的"2021年6月25日 04时50分30秒"。
cli
dateparse
还提供了一个命令行工具,用于极快地查看日期工夫格局。装置:
$ go install github.com/araddon/dateparse/dateparse
默认会装置在$GOPATH
门路下,我习惯上把$GOPATH/bin
放到$PATH
中。所以dateparse
命令能够间接应用。
dateparse
命令接管一个字符串,和一个可选的时区选项:
$ dateparse --timezone="Asia/Shanghai" "2021-06-24 06:46:08"Your Current time.Local zone is CSTLayout String: dateparse.ParseFormat() => 2006-01-02 15:04:05Your Using time.Local set to location=Asia/Shanghai CST+-------------+---------------------------+-------------------------------+-------------------------------------+| method | Zone Source | Parsed | Parsed: t.In(time.UTC) |+-------------+---------------------------+-------------------------------+-------------------------------------+| ParseAny | time.Local = nil | 2021-06-24 06:46:08 +0000 UTC | 2021-06-24 06:46:08 +0000 UTC day=4 || ParseAny | time.Local = timezone arg | 2021-06-24 06:46:08 +0000 UTC | 2021-06-24 06:46:08 +0000 UTC day=4 || ParseAny | time.Local = time.UTC | 2021-06-24 06:46:08 +0000 UTC | 2021-06-24 06:46:08 +0000 UTC day=4 || ParseIn | time.Local = nil | 2021-06-24 06:46:08 +0000 UTC | 2021-06-24 06:46:08 +0000 UTC || ParseIn | time.Local = timezone arg | 2021-06-24 06:46:08 +0800 CST | 2021-06-23 22:46:08 +0000 UTC || ParseIn | time.Local = time.UTC | 2021-06-24 06:46:08 +0000 UTC | 2021-06-24 06:46:08 +0000 UTC || ParseLocal | time.Local = nil | 2021-06-24 06:46:08 +0000 UTC | 2021-06-24 06:46:08 +0000 UTC || ParseLocal | time.Local = timezone arg | 2021-06-24 06:46:08 +0800 CST | 2021-06-23 22:46:08 +0000 UTC || ParseLocal | time.Local = time.UTC | 2021-06-24 06:46:08 +0000 UTC | 2021-06-24 06:46:08 +0000 UTC || ParseStrict | time.Local = nil | 2021-06-24 06:46:08 +0000 UTC | 2021-06-24 06:46:08 +0000 UTC || ParseStrict | time.Local = timezone arg | 2021-06-24 06:46:08 +0000 UTC | 2021-06-24 06:46:08 +0000 UTC || ParseStrict | time.Local = time.UTC | 2021-06-24 06:46:08 +0000 UTC | 2021-06-24 06:46:08 +0000 UTC |+-------------+---------------------------+-------------------------------+-------------------------------------+
输入以后本地时区,格局字符串(可用于生成同样格局的日期工夫字符串)和一个表格。表格外面的数据是别离对ParseAny/ParseIn/ParseLocal/ParseStrict
在不同的时区下调用的后果。
method
列示意调用的办法,Zone Source
列示意将本地时区设置的值,Parsed
列是以日期工夫字符串调用ParseAny()
返回的time.Time
对象的Format()
办法调用后果,Parsed: t.In(time.UTC)
列在返回的time.Time
对象调用Format()
办法前将其转为 UTC 工夫。
因为ParseAny/ParseStrict
不会思考本地时区,都是在 UTC 下解析字符串,所以这 6 行的最初两列后果都一样。
ParseIn
的第二行,将time.Local
设置为咱们通过命令行选项设置的时区,下面我设置为Asia/Shanghai
,对应的 UTC 工夫相差 8 小时。ParseLocal
也是如此。
上面是dateparse
命令行的局部源码,能够对照查看:
func main() { parsers := map[string]parser{ "ParseAny": parseAny, "ParseIn": parseIn, "ParseLocal": parseLocal, "ParseStrict": parseStrict, } for name, parser := range parsers { time.Local = nil table.AddRow(name, "time.Local = nil", parser(datestr, nil, false), parser(datestr, nil, true)) if timezone != "" { time.Local = loc table.AddRow(name, "time.Local = timezone arg", parser(datestr, loc, false), parser(datestr, loc, true)) } time.Local = time.UTC table.AddRow(name, "time.Local = time.UTC", parser(datestr, time.UTC, false), parser(datestr, time.UTC, true)) }}func parseIn(datestr string, loc *time.Location, utc bool) string { t, err := dateparse.ParseIn(datestr, loc) if err != nil { return err.Error() } if utc { return t.In(time.UTC).String() } return t.String()}
留神输入的本地时区为 CST,它能够代表不同的时区:
Central Standard Time (USA) UT-6:00Central Standard Time (Australia) UT+9:30China Standard Time UT+8:00Cuba Standard Time UT-4:00
CST 能够同时示意美国、澳大利亚、中国和古巴四个国家的规范工夫。
总结
应用dateparse
能够很不便地从日期工夫字符串中解析出工夫对象和格局(layout)。同时dateparse
命令行能够疾速的查看和转换相应时区的工夫,是一个十分不错的小工具。
大家如果发现好玩、好用的 Go 语言库,欢送到 Go 每日一库 GitHub 上提交 issue
参考
- dateparse GitHub:github.com/araddon/dateparse
- Go 每日一库 GitHub:https://github.com/darjun/go-daily-lib
我
我的博客:https://darjun.github.io
欢送关注我的微信公众号【GoUpUp】,独特学习,一起提高~