-
Notifications
You must be signed in to change notification settings - Fork 18k
time: time#Format
using time.RFC3339
using time.Time
with time.Location
Europe/London
should use +00:00
instead of Z
#68164
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
Comments
Europe/London
uses Z
not +00:00
in standard time but is not documented as suchtime#Format
using time.RFC3339
in timezone Europe/London
uses Z
not +00:00
in standard time but is not documented as such
time#Format
using time.RFC3339
in timezone Europe/London
uses Z
not +00:00
in standard time but is not documented as such
RFC 3339 Section 2: https://www.rfc-editor.org/rfc/rfc3339#section-2
Z means zero offset, not UTC itself. |
Ok, guys, checked all month, here we go: package main
import (
"fmt"
"time"
)
func main() {
tz, err := time.LoadLocation("Europe/London")
if err != nil {
panic(err)
}
dates := []time.Time{
time.Date(2024, 1, 1, 0, 0, 0, 0, tz),
time.Date(2024, 2, 1, 0, 0, 0, 0, tz),
time.Date(2024, 3, 1, 0, 0, 0, 0, tz),
time.Date(2024, 4, 1, 0, 0, 0, 0, tz),
time.Date(2024, 5, 1, 0, 0, 0, 0, tz),
time.Date(2024, 6, 1, 0, 0, 0, 0, tz),
time.Date(2024, 7, 1, 0, 0, 0, 0, tz),
time.Date(2024, 8, 1, 0, 0, 0, 0, tz),
time.Date(2024, 9, 1, 0, 0, 0, 0, tz),
time.Date(2024, 10, 1, 0, 0, 0, 0, tz),
time.Date(2024, 11, 1, 0, 0, 0, 0, tz),
time.Date(2024, 12, 1, 0, 0, 0, 0, tz),
}
for _, date := range dates {
fmt.Println(date.Format(time.RFC3339))
}
} Result : 2024-01-01T00:00:00Z
2024-02-01T00:00:00Z
2024-03-01T00:00:00Z
2024-04-01T00:00:00+01:00
2024-05-01T00:00:00+01:00
2024-06-01T00:00:00+01:00
2024-07-01T00:00:00+01:00
2024-08-01T00:00:00+01:00
2024-09-01T00:00:00+01:00
2024-10-01T00:00:00+01:00
2024-11-01T00:00:00Z
2024-12-01T00:00:00Z Hacked Fixed: package main
import (
"fmt"
"time"
)
func main() {
tz, err := time.LoadLocation("Europe/London")
if err != nil {
panic(err)
}
dates := []time.Time{
time.Date(2024, 1, 1, 0, 0, 0, 0, tz),
time.Date(2024, 2, 1, 0, 0, 0, 0, tz),
time.Date(2024, 3, 1, 0, 0, 0, 0, tz),
time.Date(2024, 4, 1, 0, 0, 0, 0, tz),
time.Date(2024, 5, 1, 0, 0, 0, 0, tz),
time.Date(2024, 6, 1, 0, 0, 0, 0, tz),
time.Date(2024, 7, 1, 0, 0, 0, 0, tz),
time.Date(2024, 8, 1, 0, 0, 0, 0, tz),
time.Date(2024, 9, 1, 0, 0, 0, 0, tz),
time.Date(2024, 10, 1, 0, 0, 0, 0, tz),
time.Date(2024, 11, 1, 0, 0, 0, 0, tz),
time.Date(2024, 12, 1, 0, 0, 0, 0, tz),
}
for _, date := range dates {
fmt.Println(date.Format("2006-01-02T15:04:05-07:00"))
}
} Result 👍 , but not good 2024-01-01T00:00:00+00:00
2024-02-01T00:00:00+00:00
2024-03-01T00:00:00+00:00
2024-04-01T00:00:00+01:00
2024-05-01T00:00:00+01:00
2024-06-01T00:00:00+01:00
2024-07-01T00:00:00+01:00
2024-08-01T00:00:00+01:00
2024-09-01T00:00:00+01:00
2024-10-01T00:00:00+01:00
2024-11-01T00:00:00+00:00
2024-12-01T00:00:00+00:00 strange is : not all months have this issue
yeah, it's +00:00 |
I don't think it's feasible for us to change this now. If you don't like the |
@ianlancetaylor to be clear, as I've mentioned:
I'm disappointed that it appears the Golang team have failed to take into account the considerations indicated, or a wider discussion on the implicit use of "Z" and early return in the codebase if offset is zero, as opposed to being an explicit UTC timezone. As noted I've been explicit in one option being better documentation that any offset of zero IS ASSUMED TO BE UTC regardless of the timezone location being used. Further, discussion points above indicate an assumption that "Z means zero offset, not UTC itself", yet the documentary evidence does not IMHO support this assertion (which is then implicit in the codebase). Finally, RFC3339 is currently in review for an update, with further implicit and explicit examples highlighting my comments in this issue. |
Also, the change in the title by @seankhliao was unwarranted and completely at odds with the actual issue. I'm not happy that was made without a note of the change of scope, or a discussion over the topic. |
time#Format
using time.RFC3339
using time.Time
with time.Location
Europe/London
should use +00:00
instead of Z
Changing the current behavior is sure to break existing working code. We aren't going to do that. We are always happy to improve the documentation. In this case I'm concerned that the documentation is already lengthy and complex and that adding more information won't actually help people. But I would be happy to look at a patch. |
I've drafted a change which I know has no hope of going through, however, is indicative of what I understand of IS8601 (see https://github.com/golang/go/blob/master/src/time/format.go#L787-L817 where RFC3339 is broken down into ISO8601 parts, and, as I've noted, IMHO, incorrectly assumes a corollary of "UTC is offset of zero" to be "zero offset is UTC" even where location information is available). https://github.com/ace-teknologi/go/blob/d9b5ea30ac12e78c65ae0e55c78f7cf88ff6a434/src/time/format.go#L787-L817 |
Lengthy documentation in the time package is probably par for the course given the innate complexity of it, and its fundamental role in the language IMHO. Happy to do so if that's the proposed path forward from the Golang team, but would thus prefer the issue to be reopened as a reference point for those changes. Further, the proposed changes to be made (immediate comment above) should IMHO be considered as part of a Golang v2 release where breaking changes would be allowed, given a fundamental assumption is not necessarily in keeping with the specs it is built on (that is, a location that is not nil or time.UTC but coincidently has an offset of |
Go version
go version go1.22.4 darwin/amd64
Output of
go env
in your module/workspace:What did you do?
Ref: https://go.dev/play/p/QLy4ID0CwiU
What did you see happen?
This is due to the following portion of code:
go/src/time/format_rfc3339.go
Lines 44 to 46 in b3b4556
Now this is understandable for timezone like
time.UTC
, however as seen above, we've loaded a timezone that has variable.What did you expect to see?
It would be great to see the following output for consistency:
However that may have breaking changes in the codebase.
An alternative would be to explicitly document
time.RFC3339
to indicate that any timezone where the offset for a particular time is zero will be returned asZ
not as+00:00
regardless of how the timezone may treat other points in time.In effect, in the absence of being able to resolve a principle of least surprise issue, it would be useful to document the early exit of the
time#appendFormatRFC3339
method with aZ
instead of an[+-]HH:MM
offset where the offset value is 0.Alternatively, a breaking change would be to validate if the time's location is
time.UTC
, and useZ
, otherwise use+00:00
.The text was updated successfully, but these errors were encountered: