summary history files

internal/tzlookup/timezonelookup.go
// tzloookup attempts to find the local olsen timezone.

package tzlookup

import (
	"errors"
	"os"
	"path"
	"path/filepath"
	"strings"
)

// New creates a new Tzlookup.
func New(localtime string, opts ...Opt) (t *Tzlookup) {
	t = &Tzlookup{localtimePath: localtime, tzName: "TZ"}
	for _, opt := range opts {
		opt(t)
	}
	return
}

// Tzlookup provides methods to lookup the local timezone.
type Tzlookup struct {
	// The path of the localtime file.
	localtimePath string

	// The environment variable name where timezone could be stored.
	tzName string
}

// Opt is a functional option for Tzlookup.
type Opt func(*Tzlookup)

// WithTZName is a function option that provides a way for the called to set the environment variable name used to lookup the local timezone.
func WithTZName(s string) Opt {
	return func(t *Tzlookup) {
		t.tzName = s
	}
}

func (t *Tzlookup) checkTZ() (localTimezone string) {
	if v, ok := os.LookupEnv(t.tzName); ok {
		localTimezone = v
	}
	return
}

func (t *Tzlookup) checkLocaltime() (string, error) {
	absPath, err := filepath.EvalSymlinks(t.localtimePath)
	if err != nil {
		return "", err
	}
	localTimezone := filepath.Base(absPath)
	localTimezoneDir := filepath.Dir(absPath)
	tzslice := []string{localTimezone}
	dirCount := strings.Count(localTimezoneDir, "/")

	for i := 1; i < dirCount; i++ {
		uctFile := path.Join(localTimezoneDir, "UCT")
		if i == (dirCount - 1) {
			return "", errors.New("Unable to find local timezone")
		}
		if _, err := os.Stat(uctFile); os.IsNotExist(err) {
			tzslice = append(tzslice, filepath.Base(localTimezoneDir))
			localTimezoneDir = filepath.Dir(localTimezoneDir)
			continue
		}
		break
	}

	for i, j := 0, len(tzslice)-1; i < j; i, j = i+1, j-1 {
		tzslice[i], tzslice[j] = tzslice[j], tzslice[i]
	}

	localTimezone = strings.Join(tzslice, "/")
	return localTimezone, nil
}

// Local attempts to lookup and return the local timezone.
func (t *Tzlookup) Local() (string, error) {
	var err error
	localTimezone := t.checkTZ()
	if localTimezone == "" {
		localTimezone, err = t.checkLocaltime()
		if err != nil {
			return "", err
		}
	}
	return localTimezone, nil
}