简介
不论什么时候,解决工夫总是让人头疼的一件事件。因为工夫格局太多样化了,再加上时区,夏令时,闰秒这些细枝末节解决起来更是艰难。所以在程序中,波及工夫的解决咱们个别借助于规范库或第三方提供的工夫库。明天要介绍的 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 main
import (
"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.go
2014-03-01 00:00:00
2021/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.go
2021/06/24 14:57:18 This date has ambiguous mm/dd vs dd/mm type format
exit status 1
格局
dateparse
反对丰盛的日期工夫格局,根本囊括了所有罕用的格局。它反对规范库 time
中预约义的所有格局:
// src/time/format.go
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 = "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.go
2021-06-25 04:50:30
2021-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 CST
Layout String: dateparse.ParseFormat() => 2006-01-02 15:04:05
Your 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:00
Central Standard Time (Australia) UT+9:30
China Standard Time UT+8:00
Cuba 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】,独特学习,一起提高~