我尝试在Go中解析日期字符串"2014-09-12T11:45:26.371Z"。此时间格式定义为:
"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"月超出范围
我如何解析这个日期字符串?
使用描述的精确布局数字在这里和一个漂亮的博客文章在这里。
所以:
layout := "2006-01-02T15:04:05.000Z" str := "2014-11-12T11:45:26.371Z" t, err := time.Parse(layout, str) if err != nil { fmt.Println(err) } fmt.Println(t)
给:
>> 2014-11-12 11:45:26.371 +0000 UTC
YYYY-MM-DD
2006-01-02T15:04:05.000Z
布局中使用的参考时间为:
Mon Jan 2 15:04:05 MST 2006
是Unix时间1136239445 由于MST为GMT-0700,所以参考时间可以认为是
1136239445
01/02 03:04:05PM '06 -0700
(1、2、3、4、5、6、7,只要你记得1代表月,2代表日,这对像我这样的欧洲人来说并不容易,因为我习惯了日-月的日期格式)
如“时间。解析:为什么golang解析时间不正确?”所示,该布局(使用1,2,3,4,5,6,7)必须遵守完全。
正如回答的那样,但为了节省为布局输入"2006-01-02T15:04:05.000Z",你可以使用包的常量RFC3339。
"2006-01-02T15:04:05.000Z"
str := "2014-11-12T11:45:26.371Z" t, err := time.Parse(time.RFC3339, str) if err != nil { fmt.Println(err) } fmt.Println(t)
https://play.golang.org/p/Dgu2ZvHwTh
这可能非常晚,但这是为那些可能无意中发现这个问题并可能想使用外部包来解析日期字符串的人准备的。
我试着找了一个图书馆,我找到了这个:
https://github.com/araddon/dateparse
来自README的例子:
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()) }
我会建议使用时间。RFC3339常量从时间包。您可以从time包中检查其他常数。 https://golang.org/pkg/time/#pkg-constants < / p >
package main import ( "fmt" "time" ) func main() { fmt.Println("Time parsing"); dateString := "2014-11-12T11:45:26.371Z" time1, err := time.Parse(time.RFC3339,dateString); if err!=nil { fmt.Println("Error while parsing date :", err); } fmt.Println(time1); }
这是一个相当晚的聚会,并没有真正说任何没有以这种或那种形式说过的东西,主要是通过上面的链接,但我想给那些注意力持续时间较短的人一个TL;DR概述:
go格式字符串的日期和时间非常重要。围棋就是这样区分哪个领域是哪个领域的。一般从左到右为1-9,如下:
所以,不要写“01-05-15”作为你的日期格式,除非你想要“月-秒-小时”
(…同样,这也是对上述内容的总结。)
如果您使用过其他语言中的时间/日期格式化/解析,您可能已经注意到其他语言使用特殊的占位符进行时间/日期格式化。例如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
如果你注意到Go使用
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。
你可以在这个链接中引用完整的占位符布局表——https://golangbyexample.com/parse-time-in-golang/
对于那些遇到这种情况的人,使用时间。RFC3339而不是"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
这里是操场上的链接