Date 解析Go中的日期字符串
我尝试在Go中解析日期字符串Date 解析Go中的日期字符串,date,go,Date,Go,我尝试在Go中解析日期字符串“2014-09-12T11:45:26.371Z” 代码 layout := "2014-09-12T11:45:26.371Z" str := "2014-11-12T11:45:26.371Z" t, err := time.Parse(layout , str) 我得到了这个错误: 解析时间“2014-11-12T11:47:39.489Z”:月份超出范围 如何解析此日期字符串?使用所描述的确切版式编号和漂亮的博客帖子 因此: 给出: >> 20
“2014-09-12T11:45:26.371Z”
代码
layout := "2014-09-12T11:45:26.371Z"
str := "2014-11-12T11:45:26.371Z"
t, err := time.Parse(layout , str)
我得到了这个错误:
解析时间“2014-11-12T11:47:39.489Z”:月份超出范围
如何解析此日期字符串?使用所描述的确切版式编号和漂亮的博客帖子 因此: 给出:
>> 2014-11-12 11:45:26.371 +0000 UTC
我知道。令人难以置信。第一次也抓住了我。
Go只是不使用datetime组件的抽象语法(
YYYY-MM-DD
),而是使用这些精确的数字(我认为Go-Nope的第一次提交时间,根据。有人知道吗?) 要使用的布局确实是“2006-01-02T15:04:05.000Z
”,如中所述。这不是“go第一次提交的时间”,而是一种记忆所述布局的方式。
见: 布局中使用的参考时间为: 这是Unix时间
1136239445
由于MST为GMT-0700,因此参考时间可被视为 (1,2,3,4,5,6,7,前提是你记住1表示月份,2表示日,这对于像我这样习惯于日-月-日格式的欧洲人来说并不容易)
如“”所示,该布局(使用1,2,3,4,5,6,7)必须严格遵守。如回答所示,但为了避免为布局键入
“2006-01-02T15:04:05.000Z”
,可以使用包的常量
这可能太晚了,但这是为那些可能偶然发现这个问题并希望使用外部包解析日期字符串的人准备的 我试着寻找一个图书馆,我发现了这个: 自述文件中的示例:
package main
import (
"flag"
"fmt"
"time"
"github.com/apcera/termtables"
"github.com/araddon/dateparse"
)
var examples = []string{
"May 8, 2009 5:57:51 PM",
"Mon Jan 2 15:04:05 2006",
"Mon Jan 2 15:04:05 MST 2006",
"Mon Jan 02 15:04:05 -0700 2006",
"Monday, 02-Jan-06 15:04:05 MST",
"Mon, 02 Jan 2006 15:04:05 MST",
"Tue, 11 Jul 2017 16:28:13 +0200 (CEST)",
"Mon, 02 Jan 2006 15:04:05 -0700",
"Thu, 4 Jan 2018 17:53:36 +0000",
"Mon Aug 10 15:44:11 UTC+0100 2015",
"Fri Jul 03 2015 18:04:07 GMT+0100 (GMT Daylight Time)",
"12 Feb 2006, 19:17",
"12 Feb 2006 19:17",
"03 February 2013",
"2013-Feb-03",
// mm/dd/yy
"3/31/2014",
"03/31/2014",
"08/21/71",
"8/1/71",
"4/8/2014 22:05",
"04/08/2014 22:05",
"4/8/14 22:05",
"04/2/2014 03:00:51",
"8/8/1965 12:00:00 AM",
"8/8/1965 01:00:01 PM",
"8/8/1965 01:00 PM",
"8/8/1965 1:00 PM",
"8/8/1965 12:00 AM",
"4/02/2014 03:00:51",
"03/19/2012 10:11:59",
"03/19/2012 10:11:59.3186369",
// yyyy/mm/dd
"2014/3/31",
"2014/03/31",
"2014/4/8 22:05",
"2014/04/08 22:05",
"2014/04/2 03:00:51",
"2014/4/02 03:00:51",
"2012/03/19 10:11:59",
"2012/03/19 10:11:59.3186369",
// Chinese
"2014年04月08日",
// yyyy-mm-ddThh
"2006-01-02T15:04:05+0000",
"2009-08-12T22:15:09-07:00",
"2009-08-12T22:15:09",
"2009-08-12T22:15:09Z",
// yyyy-mm-dd hh:mm:ss
"2014-04-26 17:24:37.3186369",
"2012-08-03 18:31:59.257000000",
"2014-04-26 17:24:37.123",
"2013-04-01 22:43",
"2013-04-01 22:43:22",
"2014-12-16 06:20:00 UTC",
"2014-12-16 06:20:00 GMT",
"2014-04-26 05:24:37 PM",
"2014-04-26 13:13:43 +0800",
"2014-04-26 13:13:44 +09:00",
"2012-08-03 18:31:59.257000000 +0000 UTC",
"2015-09-30 18:48:56.35272715 +0000 UTC",
"2015-02-18 00:12:00 +0000 GMT",
"2015-02-18 00:12:00 +0000 UTC",
"2017-07-19 03:21:51+00:00",
"2014-04-26",
"2014-04",
"2014",
"2014-05-11 08:20:13,787",
// mm.dd.yy
"3.31.2014",
"03.31.2014",
"08.21.71",
// yyyymmdd and similar
"20140601",
// unix seconds, ms
"1332151919",
"1384216367189",
}
var (
timezone = ""
)
func main() {
flag.StringVar(&timezone, "timezone", "UTC", "Timezone aka `America/Los_Angeles` formatted time-zone")
flag.Parse()
if timezone != "" {
// NOTE: This is very, very important to understand
// time-parsing in go
loc, err := time.LoadLocation(timezone)
if err != nil {
panic(err.Error())
}
time.Local = loc
}
table := termtables.CreateTable()
table.AddHeaders("Input", "Parsed, and Output as %v")
for _, dateExample := range examples {
t, err := dateparse.ParseLocal(dateExample)
if err != nil {
panic(err.Error())
}
table.AddRow(dateExample, fmt.Sprintf("%v", t))
}
fmt.Println(table.Render())
}
我建议使用time package中的time.rfc339常量。您可以检查时间包中的其他常量。
这是相当晚的党,并没有真正说什么还没有说的形式或其他,主要是通过上面的链接,但我想给一个TL;博士向注意力跨度较小的人重述: go格式字符串的日期和时间非常重要。这就是Go如何知道哪个领域是哪个领域。它们通常从左到右为1-9,如下所示:
- 1月/1月/1月/1月/01/_1(等)表示月份
- 02/_2表示月份的第几天
- 15/03/_3/PM/P/PM/P代表小时和子午线(下午3点)
- 04/_4为分钟
- 05/_5表示秒
- 2006/06年度为
- -0700/07:00/MST适用于时区
- .999999999/.000000000等表示部分秒(我认为区别在于是否删除了尾随零)
- 周一/周一是一周中的一天(实际上是2006年2月1日)
(…同样,这基本上是上面的总结。)如果您使用过其他语言的时间/日期格式设置/解析,您可能会注意到其他语言使用特殊占位符进行时间/日期格式设置。例如ruby语言的使用
%d for day
%Y for year
等等。Golang不使用上述代码,而是使用日期和时间格式的占位符,看起来只像日期和时间。Go使用标准时间,即:
Mon Jan 2 15:04:05 MST 2006 (MST is GMT-0700)
or
01/02 03:04:05PM '06 -0700
所以如果你注意到围棋的用法
01 for the day of the month,
02 for the month
03 for hours,
04 for minutes
05 for second
and so on
因此,例如,对于解析2020-01-29,布局字符串应为06-01-02或2006-01-02
您可以参考此链接中的完整占位符布局表-对于遇到此问题的用户,请使用字符串常量
“2006-01-02T15:04:05.000Z”
。原因如下:
regDate := "2007-10-09T22:50:01.23Z"
layout1 := "2006-01-02T15:04:05.000Z"
t1, err := time.Parse(layout1, regDate)
if err != nil {
fmt.Println("Static format doesn't work")
} else {
fmt.Println(t1)
}
layout2 := time.RFC3339
t2, err := time.Parse(layout2, regDate)
if err != nil {
fmt.Println("RFC format doesn't work") // You shouldn't see this at all
} else {
fmt.Println(t2)
}
这将产生以下结果:
Static format doesn't work
2007-10-09 22:50:01.23 +0000 UTC
这是一个是的,它也吸引了澳大利亚人!MM/DD对我来说根本算不上,我必须一直看下去。@SimonWhitehead我同意。至少,一旦我查到它,我知道YY,MM,DD,hh,MM,ss代表什么,我可以很容易地重新订购它们。使用Go,即使在查找之后,我也需要记住1、2、3、4。。。代表。我记得它的方式是:步骤1)“正确”的日期顺序是年>月>日>小时>分钟>秒>等等(因为混合尾数只是非感官上的任意性和不一致性,对于日期,大尾数比小尾数更可取,因为它排序友好。)这将得到1(年)、2(月)、3(天),[…]步骤2)Go/Google是美国人,美国人把他们的年份放在日期的末尾,所以它是1(月),2(日),[…],n(年)步骤3)时区排在其他所有的后面,因为时区是一个额外的抽象层。@mtraceur是的。。。我也想念你。我的意思是,
strftime
FTW.布局编号?什么?为什么?啊!他们在想什么?或者吸烟?我在这里发表评论可能有点晚了,但不要害怕带有数字的布局,只要使用常量,代码就会很干净:)例如time.rfc3339对于那些没有获得布局编号的人,我承认乍看起来很陌生,但一旦你习惯了,我认为它至少和典型的布局设备一样有意义(我是否使用“D”、“D”、“dd”、“dd”等),而且可能更有意义。你只需要先知道它。它是为了记忆,也就是说,你只需要记住1,2,3,4,5,6,7这些字母。有一篇很好的文章讨论了这一点:此外,如果您查看包常量(在上面的答案中链接),还可以使用其他一些常用格式。如果你需要一些稍有不同的东西,就把它们作为一个起点。这和一些答案建议你使用Go's时间。RFC3339也可以。但是time.RFC3339=“2006-01-02T15:04:05Z07:00”
。就time.Parse
和time.ParseInLocation
而言,这两种格式是否完全相同?这是正确的@Miles,这个测试为将来的读者确认了这一点,我写了一些练习来练习日期解析你的布局应该是2006-01-0
%d for day
%Y for year
Mon Jan 2 15:04:05 MST 2006 (MST is GMT-0700)
or
01/02 03:04:05PM '06 -0700
01 for the day of the month,
02 for the month
03 for hours,
04 for minutes
05 for second
and so on
regDate := "2007-10-09T22:50:01.23Z"
layout1 := "2006-01-02T15:04:05.000Z"
t1, err := time.Parse(layout1, regDate)
if err != nil {
fmt.Println("Static format doesn't work")
} else {
fmt.Println(t1)
}
layout2 := time.RFC3339
t2, err := time.Parse(layout2, regDate)
if err != nil {
fmt.Println("RFC format doesn't work") // You shouldn't see this at all
} else {
fmt.Println(t2)
}
Static format doesn't work
2007-10-09 22:50:01.23 +0000 UTC