-
Notifications
You must be signed in to change notification settings - Fork 17.8k
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: Parse not setting Location to Local when TZ=UTC #45960
Comments
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
I think I see the problem now main » go run .
time.Date(2021, time.May, 5, 17, 29, 40, 618448319, time.Local) "2021-05-05T17:29:40.618448319+02:00" time.Date(2021, time.May, 5, 17, 29, 40, 618448319, time.Local)
main » TZ=NZ go run .
time.Date(2021, time.May, 6, 3, 29, 47, 269450883, time.Local) "2021-05-06T03:29:47.269450883+12:00" time.Date(2021, time.May, 6, 3, 29, 47, 269450883, time.Local)
main » TZ=UTC go run .
time.Date(2021, time.May, 5, 15, 29, 54, 909582162, time.Local) "2021-05-05T15:29:54.909582162Z" time.Date(2021, time.May, 5, 15, 29, 54, 909582162, time.UTC) cc @rsc |
It's true that Why does this matter? |
the concern is that usually package main
import (
"fmt"
"time"
)
func main() {
fmt.Printf("%p\n", time.Local)
t := time.Now().Round(0)
b, err := t.MarshalJSON()
fmt.Printf("%#v, %s\n", t, err)
fmt.Println(string(b))
t = time.Time{}
err = t.UnmarshalJSON(b)
fmt.Printf("%#v, %s\n", t, err)
}
|
|
that makes sense, my request then is to never use EDIT: digging further into this, it looks like fmt.Printf("%p\n", time.Local)
t, _ := time.Parse(time.RFC3339Nano, "2021-05-20T16:03:45.330360905+12:00")
fmt.Printf("%#v\n", t)
|
I'm perhaps observing a related behaviour, which is also different between Go 1.16.4 on my local machine versus the same Go version on the playground. tr, _ := time.Parse(time.RFC3339, "2021-05-21T12:21:25.954+00:00")
fmt.Printf("%#v\n", tr)
fmt.Printf("%#v\n", tr.Location()) Local machine: $ go version
go version go1.16.4 linux/amd64
$ go run main.go
time.Time{wall:0x38dce280, ext:63757196485, loc:(*time.Location)(0xc0004e4e70)}
&time.Location{name:"", zone:[]time.zone{time.zone{name:"", offset:0, isDST:false}}, tx:[]time.zoneTrans{time.zoneTrans{when:-9223372036854775808, index:0x0, isstd:false, isutc:false}}, extend:"", cacheStart:-9223372036854775808, cacheEnd:9223372036854775807, cacheZone:(*time.zone)(0xc0004a67a0)} Go playground:
Local system has tzdata installed, importing The difference in my case seems to be that when I run with
I'm perhaps misunderstanding how |
@daenney: caution time on the playground is screwey [recte deterministic], so that things are reproducable; but I think you are stumbling over the same thing I found. |
I noticed the discrepancy with playground too and saw you mentioned the same thing. I updated my comment to include runs from my local system. On further reflection, I suppose +00:00 could also be GMT, so I suppose always parsing +00:00 as UTC wouldn't be correct. But I do wonder why with It's worth noting though, that if I do
|
I have related problems with Location. In my case the reason is that functions Lines 1073 to 1081 in 912f075
Lines 1083 to 1085 in 912f075
I faced this issue when migrating from lib/pq to pgx. This behavior ruined my tests. I had to forcely set |
Relevant, I think: #30114 (comment)
I think this is not an issue, because when TZ=UTC, then *time.Local and *time.UTC have the same contents even though they are separate variables (GoString() shows different names, but the behavior is identical unless you actually fmt the time with "%#v"). I think it works as intended for TZ=UTC. However, there is a potential issue with real locations (not UTC) that have a zero offset to UTC. They get serialized with an appended "Z" instead of the numeric zone offset, and deserializing always gives a time with the location UTC. So a serialize/deserialize roundtrip of a local time (like time.Now()) gives back the original location everywhere else, but for locations with a zero UTC offset at the time, you will instead get back UTC. This can cause peculiar results, especially for locations such as London that part of the time has a zero offset to UTC, and otherwise not due to daylight saving time. Example: https://play.golang.org/p/ema0DpRVUsu (note the last time for London) A workaround for timestamps and other use cases where it is possible to do so, is to always handle everything as UTC, so instead of writing |
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
yes
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
https://play.golang.org/p/p7UiZXcefMp
What did you expect to see?
What did you see instead?
Summary
It looks like when
time.Local
reflects utc, unmarshaling is different than to when a timezone is present. play.golang.org may seem like a poor reproducer, since time and clocks are so heavily mocked, but my system does the same thing (either without/etc/timezone
or with it pointed at/usr/share/zoneinfo/Etc/UTC
). When I provideTZ=NZ
or/etc/localtime
, we get the desired output.The text was updated successfully, but these errors were encountered: