golang / go

The Go programming language
https://go.dev
BSD 3-Clause "New" or "Revised" License
123.8k stars 17.64k forks source link

time: Incorrect Time.IsDST() result for "Europe/Dublin" when using embedded timezone info #56743

Closed Draal closed 1 year ago

Draal commented 1 year ago

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

go version
go version go1.19.3 darwin/amd64

Does this issue reproduce with the latest release?

yes

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

go env Output
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/denysmisko/Library/Caches/go-build"
GOENV="/Users/denysmisko/Library/Application Support/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOINSECURE=""
GOMODCACHE="/Users/denysmisko/Documents/projects/go/pkg/mod"
GONOPROXY="vcs.final-level.com"
GONOSUMDB="vcs.final-level.com"
GOOS="darwin"
GOPATH="/Users/denysmisko/Documents/projects/go"
GOPRIVATE="vcs.final-level.com"
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/Cellar/go/1.19.3/libexec"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/Cellar/go/1.19.3/libexec/pkg/tool/darwin_amd64"
GOVCS=""
GOVERSION="go1.19.3"
GCCGO="gccgo"
GOAMD64="v1"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD="/Users/denysmisko/Documents/projects/hacks/go/tzcheck/go.mod"
GOWORK=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -arch x86_64 -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/tz/jxsxwxzx5wvb1g1mq5tyf0vm0000gn/T/go-build24322307=/tmp/go-build -gno-record-gcc-switches -fno-common"

What did you do?

https://go.dev/play/p/YFQ7hgFMljU then same code but without export ZONEINFO=/usr/local/go/lib/time/zoneinfo.zip

What did you expect to see?

In both cases to receive DST: false (Dublin currently not in DST time zone)

What did you see instead?

if using embedded go time zone info data file IsDST function returns true instead of false

hopehook commented 1 year ago

cc @ianlancetaylor @dmitshur

ianlancetaylor commented 1 year ago

As far as I can tell from reading the tzdata files, Europe/Dublin uses standard time in the summer and reverse daylight savings time in the winter. So as best as I can tell the Go code is correctly representing the contents of the tzdata files.

From Paul Eggert (2017-12-07): The 1996 anonymous contributor's goal was to determine the correct abbreviation for summer time in Dublin and so the contributor focused on the "IST", not on the "Irish Summer Time". Though the "IST" was correct, the "Irish Summer Time" appears to have been an error, as Ireland's Standard Time (Amendment) Act, 1971 states that standard time in Ireland remains at UT +01 and is observed in summer, and that Greenwich mean time is observed in winter. (Thanks to Derick Rethans for pointing out the error.) That is, when Ireland amended the 1968 act that established UT +01 as Irish Standard Time, it left standard time unchanged and established GMT as a negative daylight saving time in winter. So, in this database IST stands for Irish Summer Time for timestamps before 1968, and for Irish Standard Time after that. See: http://www.irishstatutebook.ie/eli/1971/act/17/enacted/en/print

If anybody has better information I'd be happy to learn.

Draal commented 1 year ago

yes correct but, go time IsDST returns true on GMT isn't this incorrect? also it does return false on MacOS 2022f tzdb file

ianlancetaylor commented 1 year ago

The time package currently returns true for IsDST in the timezone Europe/Dublin, which is not the same as the timezone GMT, even though they have the same values. In the timezone GMT, IsDST appears to always return false, as it should.

I don't know what is happening on MacOS. On Ubuntu I see the same results with the embedded tzdata and with the system tzdata which is 2022c.

Draal commented 1 year ago

https://go.dev/play/p/YFQ7hgFMljU @ianlancetaylor just run this example on playground itself it returns true ^

as I said it depends on which tzdata you run it on my Debian server with 2021a-1+deb11u7 it's incorrectly true same with embedded into go 1.19.3 tzdata as well

and on MacOS is completely fine and return false as it should

ianlancetaylor commented 1 year ago

That program (https://go.dev/play/p/YFQ7hgFMljU) prints "true" on the playground, and it prints "true" on my Ubuntu system (tzdata 2022c), and it prints "true" on my Fedora system (tzdata 2022f). But it does print "false" on an old RHEL system.

I bisected on tzdata versions, and it appears to print "false" up to tzdata 2018d and to print "true" from tzdata 2018e onward. The NEWS entry for 2018e says

Bring back the negative-DST changes of 2018a, except be more
compatible with data parsers that do not support negative DST.
Also, this now affects historical timestamps in Namibia and the
former Czechoslovakia, not just Ireland.  The main format now uses
negative DST to model timestamps in Europe/Dublin (from 1971 on),
Europe/Prague (1946/7), and Africa/Windhoek (1994/2017).  This
does not affect UT offsets, only time zone abbreviations and the
tm_isdst flag.  Also, this does not affect rearguard or vanguard
formats; effectively the main format now uses vanguard instead of
rearguard format.  Data parsers that do not support negative DST
can still use data from the rearguard tarball described below.

So I really do think that Go is behaving correctly here.

Draal commented 1 year ago

@ianlancetaylor I see, was confused with negative dst, didn't know they exist