Go Tidbit: Listing All Time Zones in Go

I wanted to list all the time zones in Go.
The standard library in Go comes with the time package. It also comes with the time/tzdata package.
The standard time package in Go is very well-thought-out. It makes date-time manipulation deceptively simple.
Yet, I could not find a way to list all the time zones.
Time Zone Database

The documentation for time.LoadLocation describes how Go uses four sources of time zone data:
The directory or uncompressed zip file named by the
ZONEINFOenvironment variableThe first source allows me to specify a time zone database. But I need to include one in the system where the Go program will run.
On a Unix system, the system’s standard installation location
The second source is dependent on the operating system. The version of the database available may be different on different systems. And the system where the Go program will run may not even have one.
$GOROOT/lib/time/zoneinfo.zipThe third source depends on Go. The data is already there if you have the Go compiler tools installed on your system. The database should be consistent across all installations of the same version of Go. However, the Go program cannot use this source without the Go compiler tools installed.
The
time/tzdatapackage, if the Go program has imported itThe fourth source, the
time/tzdatapackage does not export anything. It embeds the database from the third source with the program. But, I cannot access any time zone data in the package unless I know the names.
What if I could generate the names of the time zones as a slice of strings present in the third source when compiling my Go program? And I embed the same database using the time/tzdata package.
That would be a reasonable compromise.
I can run the Go program on a system with no time zone database and rely solely on the embedded database. And I will know the names of all the time zones in the embedded database.
tzlist.go Generator

The go command has this oft-overlooked feature: go generate.
With this, I can add a go:generate directive in my Go program and generate Go files by processing the source.
I came up with this quick Go code generator:
| |
I can then create a file named tzlist.go with the following contents:
| |
And run go generate to generate the TimeZones variable in the tzlist.go file:
| |
The TimeZones variable is a slice of strings containing the names of all time zones from the zoneinfo.zip database.
Whenever Go updates the zoneinfo.zip file, I can rerun go generate to regenerate this file.
Wrap Up

In Go, I can import the time/tzdata to have a time zone database embedded in your Go program. I can achieve the same effect by building the Go program with the -tags timetzdata flag.
The Go program can use this embedded database if the time package cannot find any time zone database on the system.
But if I want a list of timezones in this embedded database, I can use the list generated ahead of compilation from the same source of truth that comes as a part of Go compiler tools: zoneinfo.zip.
Full Code

You can find the entire code for this on GitHub.
This post is 52nd of my #100DaysToOffload challenge. Want to get involved? Find out more at 100daystooffload.com.
comments powered by Disqus