Get a list of valid time zones in Go

To get a list of time zones, you can use something like:

package main

import (
    "fmt"
    "io/ioutil"
    "strings"
)

var zoneDirs = []string{
    // Update path according to your OS
    "/usr/share/zoneinfo/",
    "/usr/share/lib/zoneinfo/",
    "/usr/lib/locale/TZ/",
}

var zoneDir string

func main() {
    for _, zoneDir = range zoneDirs {
        ReadFile("")
    }
}

func ReadFile(path string) {
    files, _ := ioutil.ReadDir(zoneDir + path)
    for _, f := range files {
        if f.Name() != strings.ToUpper(f.Name()[:1]) + f.Name()[1:] {
            continue
        }
        if f.IsDir() {
            ReadFile(path + "/" + f.Name())
        } else {
            fmt.Println((path + "/" + f.Name())[1:])
        }
    }
}

output:

Africa/Abidjan
Africa/Accra
Africa/Addis_Ababa
Africa/Algiers
Africa/Asmara
Africa/Asmera
Africa/Bamako
Africa/Bangui
...

Here is an example: https://play.golang.org/p/KFGQiW5A1P-

package main

import (
    "fmt"
    "io/ioutil"
    "strings"
    "unicode"
)

func main() {
    fmt.Println(GetOsTimeZones())
}

func GetOsTimeZones() []string {
    var zones []string
    var zoneDirs = []string{
        // Update path according to your OS
        "/usr/share/zoneinfo/",
        "/usr/share/lib/zoneinfo/",
        "/usr/lib/locale/TZ/",
    }

    for _, zd := range zoneDirs {
        zones = walkTzDir(zd, zones)

        for idx, zone := range zones {
            zones[idx] = strings.ReplaceAll(zone, zd+"/", "")
        }
    }

    return zones
}

func walkTzDir(path string, zones []string) []string {
    fileInfos, err := ioutil.ReadDir(path)
    if err != nil {
        return zones
    }

    isAlpha := func(s string) bool {
        for _, r := range s {
            if !unicode.IsLetter(r) {
                return false
            }
        }
        return true
    }

    for _, info := range fileInfos {
        if info.Name() != strings.ToUpper(info.Name()[:1])+info.Name()[1:] {
            continue
        }

        if !isAlpha(info.Name()[:1]) {
            continue
        }

        newPath := path + "/" + info.Name()

        if info.IsDir() {
            zones = walkTzDir(newPath, zones)
        } else {
            zones = append(zones, newPath)
        }
    }

    return zones
}

Go's time pkg uses a timezone database.

You can load a timezone location like this:

loc, err := time.LoadLocation("America/Chicago")
if err != nil {
    // handle error
}

t := time.Now().In(loc)

The Format function is not related to setting the time zone, this function takes a fixed reference time that allows you to format the date how you would like. Take a look at the time pkg docs.

For instance:

fmt.Println(t.Format("MST")) // outputs CST

Here is a running example

Tags:

Timezone

Go