Skip to content

Object with time.Time field doesn't equal itself after gob encode/decode (go 1.9+) #22486

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
vovka667 opened this issue Oct 29, 2017 · 3 comments

Comments

@vovka667
Copy link

Please answer these questions before submitting your issue. Thanks!

What version of Go are you using (go version)?

go version go1.9.2 linux/amd64

Does this issue reproduce with the latest release?

Yes. It reproduces with Go version 1.9 and above.

What operating system and processor architecture are you using (go env)?

GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/vovka/pr/go"
GORACE=""
GOROOT="/home/vovka/.golang/stable"
GOTOOLDIR="/home/vovka/.golang/stable/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build079377208=/tmp/go-build -gno-record-gcc-switches"
CXX="g++"
CGO_ENABLED="1"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"

What did you do?

https://play.golang.org/p/Bz82uni81C

What did you expect to see?

something like this:

$ go version
go version go1.8.5 linux/amd64
$ go run main.go
gob:
        Before: &main.someObjectWithTime{Time:time.Time{sec:63644866279, nsec:191418226, loc:(*time.Location)(0x572660)}}
        After:  &main.someObjectWithTime{Time:time.Time{sec:63644866279, nsec:191418226, loc:(*time.Location)(0x572660)}}
        reflect.DeepEqual: true

What did you see instead?

$ go version
go version go1.9.2 linux/amd64
$ go run main.go
gob:
        Before: &main.someObjectWithTime{Time:time.Time{wall:0xbe7585dacdb772e0, ext:1437579, loc:(*time.Location)(0x593820)}}
        After:  &main.someObjectWithTime{Time:time.Time{wall:0xdb772e0, ext:63644866283, loc:(*time.Location)(0x593820)}}
        reflect.DeepEqual: false
@nussjustin
Copy link
Contributor

That's the expected behaviour, since encoding a time.Time strips the monotonic time part. See the part about comparisons in time.Time's documentation:

Note that the Go == operator compares not just the time instant but also the Location and the monotonic clock reading. Therefore, Time values should not be used as map or database keys without first guaranteeing that the identical Location has been set for all values, which can be achieved through use of the UTC or Local method, and that the monotonic clock reading has been stripped by setting t = t.Round(0). In general, prefer t.Equal(u) to t == u, since t.Equal uses the most accurate comparison available and correctly handles the case when only one of its arguments has a monotonic clock reading.

If you want to compare two time.Time instances you should use Time.Equal.

@ghost
Copy link

ghost commented Oct 29, 2017

Rel #22251

@ALTree
Copy link
Member

ALTree commented Oct 29, 2017

Yes, as explained above this is expected.

Closing as a dup of #22251 (and others).

@ALTree ALTree closed this as completed Oct 29, 2017
@golang golang locked and limited conversation to collaborators Oct 29, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants