How to fix broken tzdata2020c timezone database for alpine?

1.8k views Asked by At

I just stumbled upon a bug with the tzdata2020c package for alpine. It does not calculate the correct time for Europe/Berlin after the scheduled change of daylight savings time next Sunday October 25th, 2020. Version tzdata2020c uses CEST for e.g. the 31st of October 2020 and Europe/Berlin timezone whereas CET would be correct. 

Does anybody know how to manually add a new version of the tzdata2020d database which is available here.

My application, written in Go, incorrectly uses CEST for Europe/Berlin at 31st October 2020 using tzdata2020c: tzdata2020c

The same application correctly uses CET for Europe/Berlin at 31st October 2020 using tzdata2020a: tzdata2020a

1

There are 1 answers

1
Brits On

Manually installing the tzdata2020d files will not, in itself, fix this. However the following should (successfully tested with the golang:alpine docker image):

mkdir tz
cd tz
wget https://www.iana.org/time-zones/repository/releases/tzdata2020d.tar.gz
tar -xvf tzdata2020d.tar.gz
zic -b fat -d zoneinfo/ europe
cp zoneinfo/Europe/Berlin /usr/share/zoneinfo/Europe/Berlin

Other workarounds include:

  • Upgrade to Go 1.15.4 or 1.14.11.
  • Use the ZONEINFO environmental variable to select a different zone file (e.g. export ZONEINFO=/usr/local/go/lib/time/zoneinfo.zip; zoneinfo.zip is in the go installation).
  • 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)
  • 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).

Cause

This problem was caused by a change in the zic application; prior to the version included with 2020b release this defaulted to fat mode which go applications correctly processed. The default is now thin and go does not support that format (without this patch). Unfortunately the LoadLocation function fails silently (returning incorrect zone information).

The issue is likely to occur wherever 2020b or later timezone files are used (unless the package maintainer overrides the defaults when running zic).

zic details

iana distributes the timezone information as a series of text files along with a number of applications. One of these applications is zic which processes the text files into the binary files (RFC 8536) which are deployed to /usr/share/zoneinfo.

This commit changed the default output format from fat to slim. The upshot of this is that timezone files produced using the 2020b, or later, files will not be read correctly by Go (unless they are created using the -b fat argument).

Go Fix

This is fixed in Go 1.15.4 and 1.14.11.

An issue has been raised and the issue is partly fixed by a recent commit (the main aim of that commit was to reduce the size of the time/tzdata package but should also fix this). See this issue re the other part of the fix.

Testing

The following application demonstrates the issue:

package main

import (
    "fmt"
    "time"
)

func main() {
    b, err := time.LoadLocation("Europe/Berlin")
    if err != nil {
        panic(err)
    }
    t := time.Date(2020, 10, 23, 11, 00, 00, 00, time.UTC)
    fmt.Printf("1: %s %s\n", t, t.In(b))
    t = time.Date(2020, 10, 31, 11, 00, 00, 00, time.UTC)
    fmt.Printf("2: %s %s\n", t, t.In(b))
}

The output (Alpine 3.12 under Docker), as at 19th October, is:

1: 2020-10-23 11:00:00 +0000 UTC 2020-10-23 13:00:00 +0200 CEST
2: 2020-10-31 11:00:00 +0000 UTC 2020-10-31 13:00:00 +0200 CEST

This is incorrect because the 31st should be CET (Alpine 3.8 generates the correct result).