Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Parsing date/time strings which are not 'standard' formats

Tags:

time

go

How do I parse non-standard date/time strings in Go. In example if I wanted to convert the string 10/15/1983 into a 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 results in a panic.

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

Logically that makes sense because how is it supposed to 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 cannot find such a function in the Go docs, is my only choice to regex?

like image 584
Nucleon Avatar asked Dec 31 '12 22:12

Nucleon


People also ask

What are the different DateTime formats?

SSSZ string value. RFC_1123_DATE_TIME: Converts the datetime value to a [day of the week], [day of the month] [month in 'MMM' format] [year in 'YYYY' format] hh:mm:ss , or [day of the week], [day of the month] [month in 'MMM' format] [year in 'YYYY' format] hh:mm:ss+offset value string value.

What is the standard DateTime format?

Thh. ISO 8601 uses the 24-hour clock system. As of ISO 8601-1:2019, the basic format is T[hh][mm][ss] and the extended format is T[hh]:[mm]:[ss].

What is parse date time?

The Date. parse() method parses a string representation of a date, and returns the number of milliseconds since January 1, 1970, 00:00:00 UTC or NaN if the string is unrecognized or, in some cases, contains illegal date values (e.g. 2015-02-31). Only the ISO 8601 format ( YYYY-MM-DDTHH:mm:ss.


1 Answers

There are some key values that the 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 parser will recognize it.

Here's the modified 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 utilize the constants list in the src/pkg/time/format.go file to create your own parse 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 ) 

So anytime your format specifies a year, it should be done with "06" or "2006", seconds are specified by "05" or "5" and time zones are specified at "MST", "Z0700", "Z07:00", "-0700", "-07" or "-07:00". If you reference the constants list you can likely put together any standard format you'd need to parse.

For example, if you want to parse the date/time in the Common Log Format, the format Apache uses for its log files, you would do so by passing the following string to time.Parse() as the layout argument.

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

"02" denotes the day of the month field, "Jan" denotes the month name field, "2006" denotes the year field, "15" denotes the hour of day field in 24 hour format, "04" denotes the minutes field, "05" denotes the seconds field and "-0700" denotes the time zone field.

That format would parse the current PST time: 31/Dec/2012:15:32:25 -0800

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

test, err := time.Parse("02/Jan/2006:15:04:05 -0700", "31/Dec/2012:15:32:25 -0800") 
like image 174
Daniel Avatar answered Oct 17 '22 01:10

Daniel