1.问题
将一个自定义的日期格式,如"2020-08-10 15:04:35",转为时间戳:
myDateString2 := "2020-08-10 15:04:35"
myDate2, err := time.Parse("2020-08-10 15:04:35", myDateString2)
if err != nil {
log.Println("err:", err.Error())
return
}
fmt.Println("My Starting Date2:\t", myDateString2, "---->", myDate2.UnixNano()/1e6)
执行报错:
err: parsing time "2020-08-10 15:04:35" as "2020-08-10 15:04:35": cannot parse "-08-10 15:04:35" as "0-08-"
当修改layout为2016-01-02 15:04:05
,还会报错:
err: parsing time "2020-08-10 15:04:35": month out of range
2.原因
对layout解析过程中, src/pkg/time/format.g中定义了格式常量(年月日等),对常量涵盖的年月日和其他的年月日解析不同,自定义的layout可能导致解析有问题。
比如在解析年份时,如果年份不等于2006,会被解析为stdDay,那么在解析2020-08-10 15:04:35的时候年被当成2:
case '2': // 2006, 2
if len(layout) >= i+4 && layout[i:i+4] == "2006" {
return layout[0:i], stdLongYear, layout[i+4:]
}
return layout[0:i], stdDay, layout[i+1:] //不是2006 返回这个
后面的解析自然就出问题了。
3.解决
如,constant定义的年份为2006(或06),月为1月(January/1/01/Jan)..,那么在进行自定义layout时,按照constant中已经定义的就可以正常解析了
stdLongMonth = iota + stdNeedDate // "January"
stdMonth // "Jan"
stdNumMonth // "1"
stdZeroMonth // "01"
stdLongWeekDay // "Monday"
stdWeekDay // "Mon"
stdDay // "2"
stdUnderDay // "_2"
stdZeroDay // "02"
stdUnderYearDay // "__2"
stdZeroYearDay // "002"
stdHour = iota + stdNeedClock // "15"
stdHour12 // "3"
stdZeroHour12 // "03"
stdMinute // "4"
stdZeroMinute // "04"
stdSecond // "5"
stdZeroSecond // "05"
stdLongYear = iota + stdNeedDate // "2006"
stdYear // "06"
stdPM = iota + stdNeedClock // "PM"
stdpm // "pm"
stdTZ = iota // "MST"
stdISO8601TZ // "Z0700" // prints Z for UTC
stdISO8601SecondsTZ // "Z070000"
stdISO8601ShortTZ // "Z07"
stdISO8601ColonTZ // "Z07:00" // prints Z for UTC
stdISO8601ColonSecondsTZ // "Z07:00:00"
stdNumTZ // "-0700" // always numeric
stdNumSecondsTz // "-070000"
stdNumShortTZ // "-07" // always numeric
stdNumColonTZ // "-07:00" // always numeric
stdNumColonSecondsTZ // "-07:00:00"
stdFracSecond0 // ".0", ".00", ... , trailing zeros included
stdFracSecond9 // ".9", ".99", ..., trailing zeros omitted
将layout修改为里面定义了的年月日时分秒,如2006-01-02 15:04:05
即可,修改后代码:
myDate2, err := time.Parse("2006-01-02 15:04:05", myDateString2)