|
| 1 | +//go:build freebsd |
| 2 | + |
| 3 | +package tz |
| 4 | + |
| 5 | +import ( |
| 6 | + "path/filepath" |
| 7 | + "strings" |
| 8 | + "time" |
| 9 | + |
| 10 | + "golang.org/x/xerrors" |
| 11 | +) |
| 12 | + |
| 13 | +const etcLocaltime = "/etc/localtime" |
| 14 | +const zoneInfoPath = "/usr/share/zoneinfo" |
| 15 | + |
| 16 | +// TimezoneIANA attempts to determine the local timezone in IANA format. |
| 17 | +// If the TZ environment variable is set, this is used. |
| 18 | +// Otherwise, /etc/localtime is used to determine the timezone. |
| 19 | +// Reference: https://stackoverflow.com/a/63805394 |
| 20 | +// On Windows platforms, instead of reading /etc/localtime, powershell |
| 21 | +// is used instead to get the current time location in IANA format. |
| 22 | +// Reference: https://superuser.com/a/1584968 |
| 23 | +func TimezoneIANA() (*time.Location, error) { |
| 24 | + loc, err := locationFromEnv() |
| 25 | + if err == nil { |
| 26 | + return loc, nil |
| 27 | + } |
| 28 | + if !xerrors.Is(err, errNoEnvSet) { |
| 29 | + return nil, xerrors.Errorf("lookup timezone from env: %w", err) |
| 30 | + } |
| 31 | + |
| 32 | + lp, err := filepath.EvalSymlinks(etcLocaltime) |
| 33 | + if err != nil { |
| 34 | + return nil, xerrors.Errorf("read location of %s: %w", etcLocaltime, err) |
| 35 | + } |
| 36 | + stripped := strings.Replace(lp, zoneInfoPath, "", -1) |
| 37 | + stripped = strings.TrimPrefix(stripped, string(filepath.Separator)) |
| 38 | + loc, err = time.LoadLocation(stripped) |
| 39 | + if err != nil { |
| 40 | + return nil, xerrors.Errorf("invalid location %q guessed from %s: %w", stripped, lp, err) |
| 41 | + } |
| 42 | + return loc, nil |
| 43 | +} |
0 commit comments