Overcoming Go’s summer-time localization issues

If you are using local timezone formatting in your Go project, you might have experienced a sudden issue with incorrectly formatted dates over the past few days. Despite summer time ending in Europe last weekend, Go still formats the date as if it was active. So for the location of Europe/Zagreb, it still shows up as CEST instead of CET.

Photo by Bob Clark from Pexels

What happened?

If you are only using the UTC dates and do not format the dates using time.LoadLocation you are unlikely to be affected. Although, you might still be impacted if some dependency is using it.

How to reproduce it?

If we build it as a multi-stage Docker image with the latest alpine and tzdata (at the time of writing it fetches 2020c which is outdated).

When we run the image we can see that output is not the expected one. The first of November should be formatted as 13:00:00 in CET, not the CEST, since summer-time ended on October 25th, 2020.

Europe/Zagreb 2020-11-01 14:00:00 CEST

How to fix it?

As explained in the source code, Go will look for time zone definitions in an environment variable named ZONEINFO. It then fallbacks to the default Unix locations, followed by definitions bundled within Go SDK. By default alpine is not distributed with either of those, that is why we had to explicitly install them using apk add -U tzdata otherwise our app would panic.

Building the latest tzdata

Make sure to have build-essentials installed, and you can then run it using bash update.bash to get the definitions.

Injecting the latest tzdata into Docker image

If we run it again, we should see that it now works correctly.

Europe/Zagreb 2020-11-01 13:00:00 CET

Automating the process

In case you are not packing anything else into the image, you likely won’t need the apk add -U tzdata anymore as Go will use the ones we built.

Future considerations

To keep up to date, there is a mailing list you can join on the official IANA page which publishes the tzdata releases.

Big thanks to Filip Reškov for helping me trace the issue.