Reputation: 2546
I am using Golang and time.Time to Parse a given string into a time object.
Using RFC3339 and time.Parse
here is an example of my code:
t, err := time.Parse(time.RFC3339, "2020-08-08T00:22:44Z07:00")
if err != nil {
return nil, err
}
I get the follow errors.
When I include timezone offset I am getting:
ERRO[0002] parsing time "2020-08-08T00:22:44Z07:00": extra text: 07:00
When I don't include the timezone offset I am getting:
ERRO[0002] parsing time "2020-08-08T00:15:36" as "2006-01-02T15:04:05Z07:00": cannot parse "" as "Z07:00"
How do I avoid this issue when parsing time into a structured object?
Upvotes: 1
Views: 3025
Reputation: 44708
The presence of the character Z
in the Go time.RFC3339
constant "2006-01-02T15:04:05Z07:00"
does not mean that a date conforming to the pattern is supposed to include a Z
followed by the time zone offset.
In fact, a date with Z
followed by anything else is not a valid RFC3339 date. Hence, your first error extra text: 07:00
The Z
stands for "Zulu Time", i.e. UTC time zone. From the RFC3339 specs:
Z A suffix which, when applied to a time, denotes a UTC offset of 00:00; often spoken "Zulu" from the ICAO phonetic alphabet representation of the letter "Z".
So the Z
alone is already providing the time zone information, that is, UTC.
As @Flimzy noted in the comments, 2020-08-08T00:22:44Z
would be a valid RFC3339 date.
t, err := time.Parse(time.RFC3339, "2020-08-08T00:22:44Z")
if err != nil {
panic(err)
}
fmt.Println(t) // 2020-08-08 00:22:44 +0000 UTC
Now, if you read the RFC3339 standard further, you see this definition:
time-zone = "Z" / time-numoffset time-numoffset = ("+" / "-") time-hour [[":"] time-minute]
Which means that the time zone part of the date is either a Z
or the offset. Clearly, since the Z
already represents the offset 00:00
, you can't have one more +/-HH:mm
offset in the same date string.
But this also means that Z
or the +/-HH:mm
must be present. So if you remove both of them, you get your second error: cannot parse "" as "Z07:00"
The parser is attempting to read the "2020-08-08T00:15:36"
string as RFC3339 so it expects either a Z
or an offset after the seconds (or milliseconds, if any).
In conclusion, the Z07:00
in the Go time.RFC3339
pattern is just a representation of the fact that the date string is supposed to include a time zone. A valid RFC3339 date string must include either Z
or the offset.
Upvotes: 5