Home > Mobile >  How to parse CCYY-MM-DDThh:mm:ss[.sss...] date format
How to parse CCYY-MM-DDThh:mm:ss[.sss...] date format

Time:04-16

As we all know, date parsing in Go has it's quirks*.

However, I have now come up against needing to parse a datetime string in CCYY-MM-DDThh:mm:ss[.sss...] to a valid date in Go.

This CCYY format is a format that seems to be ubiquitous in astronomy, essentially the CC is the current century, so although we're in 2022, the century is the 21st century, meaning the date in CCYY format would be 2122.

How do I parse a date string in this format, when we can't specify a coded layout?

Should I just parse in that format, and subtract one "century" e.g., 2106 becomes 2006 in the parsed datetime...?

Has anyone come up against this niche problem before?

*(I for one would never have been able to remember January 2nd, 3:04:05 PM of 2006, UTC-0700 if it wasn't the exact time of my birth! I got lucky)

CodePudding user response:

The time package does not support parsing centuries. You have to handle it yourself.

Also note that a simple subtraction is not enough, as e.g. the 21st century takes place between January 1, 2001 and December 31, 2100 (the year may start with 20 or 21). If the year ends with 00, you do not have to subtract 100 years.

I would write a helper function to parse such dates:

func parse(s string) (t time.Time, err error) {
    t, err = time.Parse("2006-01-02T15:04:05[.000]", s)
    if err == nil && t.Year()0 != 0 {
        t = t.AddDate(-100, 0, 0)
    }
    return
}

Testing it:

fmt.Println(parse("2101-12-31T12:13:14[.123]"))
fmt.Println(parse("2122-10-29T12:13:14[.123]"))
fmt.Println(parse("2100-12-31T12:13:14[.123]"))
fmt.Println(parse("2201-12-31T12:13:14[.123]"))

Which outputs (try it on the Go Playground):

2001-12-31 12:13:14.123  0000 UTC <nil>
2022-10-29 12:13:14.123  0000 UTC <nil>
2100-12-31 12:13:14.123  0000 UTC <nil>
2101-12-31 12:13:14.123  0000 UTC <nil>

As for remembering the layout's time:

January 2, 15:04:05, 2006 (zone: -0700) is a common order in the US, and in this representation parts are in increasing numerical order: January is month 1, 15 hour is 3PM, year 2006 is 6. So the ordinals are 1, 2, 3, 4, 5, 6, 7.

CodePudding user response:

I for one would never have been able to remember January 2nd, 3:04:05 PM of 2006, UTC-0700 if it wasn't the exact time of my birth! I got lucky.


The reason for the Go time package layout is that it is derived from the Unix (and Unix-like) date command format. For example, on Linux,

$ date
Fri Apr 15 08:20:43 AM EDT 2022
$

Now, count from left to right,

Month    = 1
Day      = 2
Hour     = 3 (or 15 = 12   3)
Minute   = 4
Second   = 5
Year     = 6

Note: Rob Pike is an author of The Unix Programming Environment

  • Related