Skip to content

Invalid example for RFC3339 time layout - Invalid according to RFC and also time.Parse fails #71377

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

Closed
lazysegtree opened this issue Jan 22, 2025 · 11 comments

Comments

@lazysegtree
Copy link

Go version

go version go1.21.6 darwin/arm64

Output of go env in your module/workspace:

GO111MODULE=''
GOARCH='arm64'
GOBIN=''
GOCACHE='/Users/kuknitin/Library/Caches/go-build'
GOENV='/Users/kuknitin/Library/Application Support/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='arm64'
GOHOSTOS='darwin'
GOINSECURE=''
GOMODCACHE='/Users/kuknitin/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='darwin'
GOPATH='/Users/kuknitin/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/opt/homebrew/Cellar/go/1.21.6/libexec'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/opt/homebrew/Cellar/go/1.21.6/libexec/pkg/tool/darwin_arm64'
GOVCS=''
GOVERSION='go1.21.6'
GCCGO='gccgo'
AR='ar'
CC='cc'
CXX='c++'
CGO_ENABLED='1'
GOMOD='/dev/null'
GOWORK=''
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
PKG_CONFIG='pkg-config'
GOGCCFLAGS='-fPIC -arch arm64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -ffile-prefix-map=/var/folders/tp/8gddycn174j124g7lkl42trh0000gn/T/go-build1722890158=/tmp/go-build -gno-record-gcc-switches -fno-common'

What did you do?

Used the provided example for RFC3339 time layout (https://github.com/golang/go/blob/master/src/time/format.go#L119) , and tried to parse it via time.Parse

Go code

// Output is
// parsing time "2006-01-02T15:04:05Z07:00": extra text: "07:00"
package main 
import (
	"fmt"
	"time"
)
func main() {
	str_to_parse := time.RFC3339
	t,err := time.Parse(time.RFC3339, str_to_parse)
	if err!=nil {
		fmt.Println(err)
	} else {
		fmt.Println("Parse done : ", t)
	}
}

What did you see happen?

(.venv) ➜  ~/Workspace/kuknitin/shared/Misc/Go git:(main) ✗ [3:38:43] go run Learning/misc/time/rfc3339_bug.go
parsing time "2006-01-02T15:04:05Z07:00": extra text: "07:00"
(.venv) ➜  ~/Workspace/kuknitin/shared/Misc/Go git:(main) ✗ [3:40:00]

What did you expect to see?

Correct output with parse done.

@lazysegtree
Copy link
Author

lazysegtree commented Jan 22, 2025

Also as per RFC - https://datatracker.ietf.org/doc/html/rfc3339#section-5.8, 2006-01-02T15:04:05Z07:00 is invalid.

Correct layout is 2006-01-02T15:04:05-07:00

@lazysegtree
Copy link
Author

lazysegtree commented Jan 22, 2025

I went through the issue - #9346, and stackoverflow discussion.
But I dont understand how it is concluded.
Either

  • we need to fix the example 2006-01-02T15:04:05Z07:00 to 2006-01-02T15:04:05-07:00 (correct)
  • Or make the time.Parse() able to parse the 2006-01-02T15:04:05Z07:00 (even though its invalid as per RFC)

The failure of time.Parse(time.RFC3339, time.RFC3339) is completely unacceptable. Its like the language is not adhering to its own definitions

@gopherbot
Copy link
Contributor

Change https://go.dev/cl/643258 mentions this issue: time: fix example for RFC3339 time layout

@lazysegtree
Copy link
Author

lazysegtree commented Jan 22, 2025

All the above issues and Stackoverflow discussion agree with that fact that package documentation for RFC3339 is wrong, and time.RFC3339 format is a case where the format string itself isn't a valid time at the moment.

So, the documentation and example should be fixed.

@lazysegtree
Copy link
Author

lazysegtree commented Jan 22, 2025

This issue is indeed the duplicate of the above mentioned issues, but the above mentioned issues have been closed without a conclusion / fix.

I have created a PR for this - #71378

@lazysegtree
Copy link
Author

lazysegtree commented Jan 22, 2025

@seankhliao Can you reopen this issue (Please see my above comments)

@seankhliao
Copy link
Member

seankhliao commented Jan 22, 2025

we've repeatedly stated that we need extra control over how exactly to parse or format the time. it's also stated in the docs:

Some valid layouts are invalid time values for time.Parse, due to formats such as _ for space padding and Z for zone information.

this is working as intended. the assumption that a layout time string has to be a valid time is unfounded.

@JoesSon72

This comment has been minimized.

@lazysegtree
Copy link
Author

lazysegtree commented Jan 22, 2025

@seankhliao

the assumption that a layout time string has to be a valid time is unfounded.

This doesn't make sense. If its not a valid time string for the given layout, what is the purpose of the layout string value ? Why dont just define time.RFC3339 to any random unique identified.

Its clearly stated in the comments of the code https://github.com/golang/go/blob/master/src/time/format.go

// These are predefined layouts for use in [Time.Format] and [time.Parse].
// The reference time used in these layouts is the specific time stamp:
//
// 01/02 03:04:05PM '06 -0700
//
// (January 2, 15:04:05, 2006, in time zone seven hours west of GMT).

Then, time.RFC3339 string value should be exactly what is the correct value for the specified time in RFC33339 format, and nothing else.

we need extra control over how exactly to parse or format the time

I dont understand how having an invalid format example gives any extra control to parse the time.
time.RFC3339 is not used by the actual parser at all.

Some valid layouts are invalid time values for time.Parse

This is not true, 2006-01-02T15:04:05Z07:00 is neither a valid layout as per RFC3339, and nor a valid time value for time.Parse. This doesn't makes any sense to use a value in example that is both invalid per the RFC, and invalid per the time.Parse implementation.

@seankhliao
Copy link
Member

as stated above, and in the docs, a layout is not necessarily a valid timestamp, it only describes the format which the time package should use to process the time. they are not example strings of valid timestamps, they are instructions to the parser and formatter. while in most cases it will look similar to a valid timestamp, that will not always be the case (_, Z).

for questions please refer to https://github.com/golang/go/wiki/Questions

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants