Handling timezones in Go

Kamal Namdeo
Image Courtesy — https://www.stickykart.com/product/golang-gopher-ninja-4/

Many beginner developers get confused in dealing with timezones. This article explains -

  • How to store them in DB?
  • How to parse them in Go?

When timezone is stored in DB, always stick to one standard timezone, the ideal would be to save UTC time and while presenting them, convert it to various timezones as per requirement.

I am taking MySQL as an example of storing time, but the below solution is DB agnostic. As per MySQL documentation, There are two ways one can store time in MySQL.

  • DATETIME — The DATETIME type is used for values that contain both date and time parts. MySQL retrieves and displays DATETIME values in 'YYYY-MM-DD hh:mm:ss' format. The supported range is '1000-01-01 00:00:00' to '9999-12-31 23:59:59'.
  • TIMESTAMP — The TIMESTAMP datatype is used for values that contain both date and time parts. TIMESTAMP has a range of '1970-01-01 00:00:01' UTC to '2038-01-19 03:14:07' UTC.

In this article, I will use DATETIME for example.

Now, the other and most important thing is to read and convert it into any timezone.

Below is an example of how we can achieve this in Go. Let’s first define a map from country to IANA identifiers: https://www.iana.org/time-zone and some utility functions.

Lets’s test this below code.

You can play with the full example in the Go playground https://play.golang.org/p/UCKSpIWmiX7

Caveat:

As per go documentation of Load location, The time zone database needed by LoadLocation may not be present on all systems, especially non-Unix systems. LoadLocation looks in the directory or uncompressed zip file named by the ZONEINFO environment variable, if any, then looks in known installation locations on Unix systems, and finally looks in $GOROOT/lib/time/zoneinfo.zip.

With Docker:

By default, it comes with Go installation. but in case you deploy using Docker and build multi-stage docker Alpine image. You can add line given below.

RUN apk add tzdata

This will add timezone information into /usr/share/timezone in the alpine image.

Also, do not forget to set the Environment variable ZONEINFO to /usr/share/timezone.

ZONEINFO=/usr/share/timezone

Just for reference, Below is the sample Dockerfile.


So, that’s how I solved my problem. Hope sharing this would help! I hope you enjoyed reading the article! Feedbacks are welcome.

Kamal Namdeo

Written by

Software Engineer, Love Distributed Systems

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade