New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

time: RFC3339 time.Parse can not parse string that come from time.Format #20555

Open
bronze1man opened this Issue Jun 2, 2017 · 7 comments

Comments

Projects
None yet
6 participants
@bronze1man
Copy link

bronze1man commented Jun 2, 2017

Please answer these questions before submitting your issue. Thanks!

What did you do?

ttps://play.golang.org/p/BItq172M-_
The bad time string "0007-05-31T3:50:00+99:80"

What did you expect to see?

0001-01-01 00:00:00 +0000 UTC xxx some error

What did you see instead?

0007-05-31 03:50:00 +10020 +10020 <nil>
0007-05-31T03:50:00+100:20
0001-01-01 00:00:00 +0000 UTC parsing time "0007-05-31T03:50:00+100:20" as "2006-01-02T15:04:05Z07:00": cannot parse "+100:20" as "Z07:00"

Because the RFC3339 parse/format is using in json.
This may curse some crashes with special user input and developer assumes that json.Unmarshal is not return an error equals to json.Unmarshal/json.Marshal/json.Unmarshal will not return an error

This string is found by using https://github.com/dvyukov/go-fuzz

@bronze1man bronze1man changed the title time: RFC3339 can not parse string that come from Format. time: RFC3339 time.Parse can not parse string that come from time.Format Jun 2, 2017

@ianlancetaylor

This comment has been minimized.

Copy link
Contributor

ianlancetaylor commented Jun 2, 2017

This is not a bug in the time package. It's true that you can format a time using time.RFC3339 that you can not parse with time.RFC3339. That is perhaps unfortunate but it follows from the documentation.

Can you express this as an issue about encoding/json?

@bronze1man

This comment has been minimized.

Copy link

bronze1man commented Jun 3, 2017

"Can you express this as an issue about encoding/json?"
https://play.golang.org/p/r6XY9LyWqu

I assumes that I can json.Unmarshal A to B successfully,so I can json.Marshal B to C,and I can json.Unmarshal C to D successfully.
But the package encoding/json and time do not behavior like what i assumes with this special user input:

[]byte(`"0007-05-31T3:50:00+99:80"`)
@kennygrant

This comment has been minimized.

Copy link
Contributor

kennygrant commented Oct 28, 2017

The RFC defines time-numoffset in terms of time-hour and time-minute which are limited to 0-24 and 0-59. From a quick look I can't see any checking on zone offsets (other fields are checked) in the source for the parse() function, could this be added? Otherwise should it just be noted in docs that zone offsets are not range checked?

This does seem rather theoretical as the offset is invalid (I think, unless I'm reading the RFC wrong), but it might be worth documenting or returning an out of range error.

https://tools.ietf.org/html/rfc3339#section-5.6

Time:

   time-hour         = 2DIGIT ; 00-24
   time-minute       = 2DIGIT ; 00-59
   time-second       = 2DIGIT ; 00-58, 00-59, 00-60 based on
                              ; leap-second rules
   time-fraction     = ("," / ".") 1*DIGIT
   time-numoffset    = ("+" / "-") time-hour [[":"] time-minute]
   time-zone         = "Z" / time-numoffset
@ippoippo

This comment has been minimized.

Copy link

ippoippo commented Mar 30, 2018

I've just been hit by this issue.

I would expect "2018-01-16T05:15:37Z" to be valid input and handled by time.RFC3339, but "2018-01-16T5:15:37Z" is not valid due to missing leading zero on the Hour.

It seems rather inconsistent....

  • Month with 01 - Expects leading zeros
  • Hour with 3 formatter value - 12H with optional leading zeros
  • Hour with 03 formatter value - 12H with mandatory leading zeros
  • Hour with 15 formatter value - 24H with optional leading zeros
  • 24H with mandatory leading zeros use case is missing ?
@andybons

This comment has been minimized.

Copy link
Member

andybons commented Apr 11, 2018

It seems that Parse and Format should be symmetric in their behavior. Marking for consideration in Go2 at least.

@andybons andybons added the Go2 label Apr 11, 2018

@andybons andybons added this to the Go2 milestone Apr 11, 2018

@ianlancetaylor

This comment has been minimized.

Copy link
Contributor

ianlancetaylor commented Apr 17, 2018

Making them fully symmetric seems reasonable, but it also seems quite hard to do it in a backward compatible manner. And even if we want to automatically fix existing uses, it seems quite hard to do so with complete reliability.

@geocode

This comment has been minimized.

Copy link

geocode commented Nov 20, 2018

I would like to add my experience to this. Would really love to see a fix for this. Many systems (including fmt.Println(someTime) output the time as YYYY-MM-DDTHH:MM:SS.sss+HHMM (note no colon on offset).

The RFC 3339 spec notes that the colon is optional for the offset (see https://tools.ietf.org/html/rfc3339#appendix-A). Because the json.Unmarshal() automatically uses the RFC3339 as the format, this prevents Go from parsing many versions of the standard timestamp format in its acceptance of json.

All of these should be valid:
"2006-01-02T15:04:05+0000"
"2006-01-02T15:04:05-0000"

I'm wonder if supporting the colon in the offset being optional really requires waiting for Go 2?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment