Parsing date / time strings that are not “standard” formats

How to handle custom date / time strings in Go. In the example, if I would like to convert the string 10/15/1983 to time.Time ? The time.Parse() function supposedly allows you to specify a format.

http://play.golang.org/p/v5DbowXt1x

 package main import "fmt" import "time" func main() { test, err := time.Parse("10/15/1983", "10/15/1983") if err != nil { panic(err) } fmt.Println(test) } 

This leads to panic.

panic: parsing time "10/15/1983" as "10/15/1983": cannot parse "" as "0/"

Logically, this makes sense, because how should he know which is the day and which is the month.

Other languages ​​have a function similar to the following:

parse("mm/dd/yyyy", "10/15/1983")

I can't find such a function in Go docs, is the only choice for regex?

+67
time go
Dec 31 '13 at 22:32
source share
2 answers

There are several key values ​​that time.Parse is looking for.

By changing:

 test, err := time.Parse("10/15/1983", "10/15/1983") 

to

 test, err := time.Parse("01/02/2006", "10/15/1983") 

the analyzer recognizes it.

Here's the changed code on the playground .

 package main import "fmt" import "time" func main() { test, err := time.Parse("01/02/2006", "10/15/1983") if err != nil { panic(err) } fmt.Println(test) } 


You can use the constant list in the src / pkg / time / format.go file to create your own parsing formats.

 const ( stdLongMonth = "January" stdMonth = "Jan" stdNumMonth = "1" stdZeroMonth = "01" stdLongWeekDay = "Monday" stdWeekDay = "Mon" stdDay = "2" stdUnderDay = "_2" stdZeroDay = "02" stdHour = "15" stdHour12 = "3" stdZeroHour12 = "03" stdMinute = "4" stdZeroMinute = "04" stdSecond = "5" stdZeroSecond = "05" stdLongYear = "2006" stdYear = "06" stdPM = "PM" stdpm = "pm" stdTZ = "MST" stdISO8601TZ = "Z0700" // prints Z for UTC stdISO8601ColonTZ = "Z07:00" // prints Z for UTC stdNumTZ = "-0700" // always numeric stdNumShortTZ = "-07" // always numeric stdNumColonTZ = "-07:00" // always numeric ) 

Therefore, at any time, the year is indicated in your format, this must be done using "06" or "2006", seconds are indicated by "05" or "5", and time zones are indicated in "MST", "Z0700", Z07: 00 "," -0700 "," -07 "or" -07: 00 ". If you refer to a list of constants, you can compile any standard format that you need for parsing.

For example, if you want to parse date / time in a common log format , the format that Apache uses for its log files, you would do this by passing the following line to time.Parse() as the layout argument.

 "02/Jan/2006:15:04:05 -0700" 

“02” means the month field of the month, “Yang” means the month name field, “2006” means the year field, “15” means the day field of the day in a 24-hour format, “04” means the minute field, “05” means the second field, and "-0700" indicates the time zone field.

This format will analyze the current time. PST: 31/Dec/2012:15:32:25 -0800

So the call to time.Parse() would look like this:

 test, err := time.Parse("02/Jan/2006:15:04:05 -0700", "31/Dec/2012:15:32:25 -0800") 
+149
Dec 31 '13 at 22:36
source share

If you cannot remember the numbers in the given layout ("2006-01-02T15: 04: 05.000Z"), you can use my simple date formatting library github.com/metakeule/fmtdate , which uses MS Excel conventions such as Y, M, D, h and internally translates them into a number format:

 package main import ( "github.com/metakeule/fmtdate" "fmt" ) func main() { test, err := fmtdate.Parse("MM/DD/YYYY", "10/15/1983") if err != nil { panic(err) } fmt.Println(test) } 
+6
May 2 '15 at 8:25
source share



All Articles