go: time: Location interprets wrong timezone (DST) with slim zoneinfo [1.15 backport]

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

$ go version
go version go1.15.3 linux/amd64

Does this issue reproduce with the latest release?

Yes, but it seems to be fixed in master with d83168eb385f7ae38710028fff5c84252267adbc.

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

go env Output
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/root/.cache/go-build"
GOENV="/root/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build587886067=/tmp/go-build -gno-record-gcc-switches"

What did you do?

How to reproduce: https://gist.github.com/hlubek/f46a73bc9d150cf1f2af585b0849e3d9

  • Added a compiled Go binary to a very simple Alpine Docker image with installed tzdata package
  • Timezones (e.g. Europe/Berlin) uses wrong daylight saving information (e.g. CEST instead of CET for dates after October, 25th in 2020)
  • This seems to be caused by changes in the tzdata package in Alpine
  • It does not occur if the tzdata Alpine package is not installed and the embedded zoneinfo time/tzdata is used

What did you expect to see?

  • An error when loading the location with a non compatible zoneinfo

What did you see instead?

  • A wrongly interpreted date

Notes

This is already fixed with d83168eb385f7ae38710028fff5c84252267adbc but I wonder why there is no info about that issue (took me some time to figure it out) or a test for the code added to zoneinfo_read.go. This is quite a standard setup for packaging Go programs so I could think many people are affected by this. The fix turns out to only work if the cached zone for now() is the same as the last transition. This broke after the last clock change on October, 25th for CET/CEST.

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 1
  • Comments: 36 (15 by maintainers)

Commits related to this issue

Most upvoted comments

I believe this may be a broader issue. This commit to zic changed the default format from fat to slim and that change was pushed out with the 2020b release. This means that the issue is likely to occur wherever 2020b or later timezone files are used (unless the package maintainer overrides the defaults when running zic). With daylight saving ending in many countries this weekend this issue may have a significant impact.

Edit: For those looking for a workaround here are a few options until a fix is released:

  • Use the ZONEINFO environmental variable to select a different zone file (e.g. export ZONEINFO=/usr/local/go/lib/time/zoneinfo.zip github ).
  • Include the tzdata package in your app (and do not install tzdata in the container - the package is only used if the time package cannot find tzdata files on the system).
  • Use a container built from scratch (in combination with one of the above options)
  • Recompile the relevant tz files in ‘fat’ mode (instructions)
  • Pin an earlier alpine version (i.e. alpine:3.8) that uses 2020a or earlier (note that version 3.8 is past its End of Support date).

For those looking for a workaround here are a few options until a fix is released: Use the ZONEINFO environmental variable to select a different zone file (e.g. export ZONEINFO=/usr/local/go/lib/time/zoneinfo.zip github ).

curious: what’s the downside of using /usr/local/go/lib/time/zoneinfo.zip all the time (not as a “workaround”, regardless of whether 1.15 etc is patched) instead of depending on another packaging system (alpine tzdata) ?

UPDATE: relying on Go toolchain update schedule for time zone data updates isn’t the best setup. e.g. there could be projects that for whatever reason need to be pegged at certain Go versions, and having that to mean the time zone info is also outdated isn’t right 🙇‍♂️ Thanks Matt

Earlier than next week? It’s already Thursday, and we don’t want to make a release on Friday, so I don’t see how we can do earlier than next week.

There is an easy temporary workaround for Go 1.15: go build -tags=timetzdata. See https://golang.org/pkg/time/tzdata.

We usually do minor releases at the start of each month, so, if all goes well, next week.

This should now be fixed on the 1.15 release branch.

gopherbot why are you closing this issue?

If need be, I suspect (for go1.15.x) one might be able to build with -tags timetzdata to work around this too. If you embed a non-slim tz file during build and then it can be deployed anywhere… maybe?

We all run into this on 17th Oct. oh, btw, we switched to distroless docker image in order to solve the problem.

On Tue, Oct 27, 2020 at 19:42 Rob Lowcock notifications@github.com wrote:

This caused us a few problems as we were using alpine:latest as our base image, which currently uses 2020c-r0 for tzdata. For anyone looking for a workaround, we pinned our version to alpine:3.8 and that seemed to do the trick (as it uses 2020a-r0).

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/golang/go/issues/42138#issuecomment-717411178, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAE7EMDTHLRHDOUWVQDVWWTSM4A73ANCNFSM4S2YPIFA .

Sorry to bother but I’m able to understand if there is any workaround while the new version is released (which is not using the release branch one I mean).

A temporary workaround is described in https://github.com/golang/go/issues/42138#issuecomment-719057910

This caused us a few problems as we were using alpine:latest as our base image, which currently uses 2020c-r0 for tzdata. For anyone looking for a workaround, we pinned our version to alpine:3.8 and that seemed to do the trick (as it uses 2020a-r0).