Go每日一库之dateparse处理时间
简介
不管什么时候,处理时间总是让人头疼的一件事情。因为时间格式太多样化了,再加上时区,夏令时,闰秒这些细枝末节处理起来更是困难。所以在程序中,涉及时间的处理我们一般借助于标准库或第三方提供的时间库。今天要介绍的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:https://github.com/araddon/dateparse
Go 每日一库 GitHub:https://github.com/darjun/go-daily-lib
到此这篇关于Go每日一库之dateparse处理时间的文章就介绍到这了,更多相关Go dateparse处理时间内容请搜索猪先飞以前的文章或继续浏览下面的相关文章希望大家以后多多支持猪先飞!
相关文章
- 这篇文章主要介绍了在java中获取List集合中最大的日期时间操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-08-15
- 在程序员中,尤其是go新手,经常听到的一个讨论话题是:如何处理错误,这篇文章主要给大家介绍了关于Go应用中优雅处理Error的一些相关技巧,需要的朋友可以参考下...2021-09-08
- 这篇文章主要介绍了教你怎么用Java获取国家法定节假日,文中有非常详细的代码示例,对正在学习java的小伙伴们有非常好的帮助,需要的朋友可以参考下...2021-04-23
- 这篇文章主要介绍了.NET/C# 使用Stopwatch测量运行时间,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-06-25
mysql中获取一天、一周、一月时间数据的各种sql语句写法
创建表:复制代码 代码如下:create table if not exists t( id int, addTime datetime default '0000-00-00 00:00:00′)添加两条初始数据:insert t values(1, '2012-07-12 21:00:00′);insert t values(2, '2012-07...2014-05-31Django def clean()函数对表单中的数据进行验证操作
这篇文章主要介绍了Django def clean()函数对表单中的数据进行验证操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-07-09- 常用的日期时间正则表达式 下面收藏了大量的日期时间正则匹配函数,包括分钟,时间与秒都能达到。 正则表达式 (?n:^(?=d)((?<day>31(?!(.0?[2469]|11))|30(?!.0?2)|29(...2016-11-25
- 实例讲解之前,先来介绍几个核心函数: mktime 函数 mktime() 函数返回一个日期的 Unix 时间戳。 参数总是表示 GMT 日期,因此 is_dst 对结果没有影响。 参数可以从右到左依次空着,空着的参数会被设为相应的当前 GMT 值。...2015-11-08
- 想在网页中动态地显示当前系统的时间,找了好多,不过都是一些停在那里不动的。。。不过皇天不负有心人,终于让我找到了...2020-06-25
- 这篇文章主要介绍了postgresql 中的时间处理小技巧(推荐),本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-03-29
- 这篇文章主要给大家介绍了关于C#使用TimeSpan时间计算的相关资料,以及通过一个实例代码给大家介绍了C#使用timespan和timer完成一个简单的倒计时器的方法,需要的朋友可以参考借鉴,下面随着小编来一起学习学习吧...2020-06-25
- /*解决代码高亮太长不换行*/ .syntaxhighlighter{word-break:break-all;} uParse('#newstext', {rootPath: '/e/extend/ueditor/'}) 帝国CMS显示指定时间内更新的信息数...2016-11-01
- 这篇文章主要介绍了C# 当前系统时间获取及时间格式详解的相关资料,这里提供代码实例,帮助大家学习参考,需要的朋友可以参考下...2020-06-25
- 这篇文章主要介绍了C#获取文件创建时间的方法,涉及C#文件操作的技巧及CreattionTime属性的使用方法,需要的朋友可以参考下...2020-06-25
PowerShell中使用Get-Date获取日期时间并格式化输出的例子
这篇文章主要介绍了PowerShell中使用Get-Date获取日期时间并格式化输出的例子,本文讲解了直接调用Get-Date、在Write-Host中使用Get-Date、格式化输出的方法,需要的朋友可以参考下...2020-06-30php 获取今日、昨日、上周、本月的起始时间戳和结束时间戳的方法
php获取今日开始时间戳和结束时间戳$beginToday=mktime(0,0,0,date('m'),date('d'),date('Y'));$endToday=mktime(0,0,0,date('m'),date('d')+1,date('Y'))-1;//php获取昨日起始时间戳和结束时间...2013-10-04- 这篇文章主要介绍了Mybatis和Mybatis-Plus时间范围查询方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-08-06
- 这篇文章主要介绍了Vue 中获取当前时间并实时刷新,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2020-05-13
- 这篇文章主要介绍了golang官方嵌入文件到可执行程序,本文通过示例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-02-20
- 这篇文章主要介绍了go浮点数转字符串保留小数点后N位解决办法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2020-05-11