1
0
mirror of https://github.com/golang/go synced 2024-11-11 22:20:22 -07:00

time: defer loading ZONEINFO until first time.LoadLocation call

A user application can now use os.Setenv("ZONEINFO", ..) becase the
value is no longer read on init of the time package.

Fixes #18619

Change-Id: Id8e303d67e6fb9c5d6ea9f969d8c94f6fff1bee3
Reviewed-on: https://go-review.googlesource.com/35639
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
Jeff Johnson 2017-01-24 11:45:20 -08:00 committed by Brad Fitzpatrick
parent ed8c62b7fb
commit 6d6360648a
3 changed files with 43 additions and 3 deletions

View File

@ -18,6 +18,15 @@ func ForceUSPacificForTesting() {
localOnce.Do(initTestingZone)
}
func ZoneinfoForTesting() *string {
return zoneinfo
}
func ResetZoneinfoForTesting() {
zoneinfo = nil
zoneinfoOnce = sync.Once{}
}
var (
ForceZipFileForTesting = forceZipFileForTesting
ParseTimeZone = parseTimeZone

View File

@ -256,7 +256,8 @@ func (l *Location) lookupName(name string, unix int64) (offset int, isDST bool,
// NOTE(rsc): Eventually we will need to accept the POSIX TZ environment
// syntax too, but I don't feel like implementing it today.
var zoneinfo, _ = syscall.Getenv("ZONEINFO")
var zoneinfo *string
var zoneinfoOnce sync.Once
// LoadLocation returns the Location with the given name.
//
@ -279,8 +280,12 @@ func LoadLocation(name string) (*Location, error) {
if name == "Local" {
return Local, nil
}
if zoneinfo != "" {
if z, err := loadZoneFile(zoneinfo, name); err == nil {
zoneinfoOnce.Do(func() {
env, _ := syscall.Getenv("ZONEINFO")
zoneinfo = &env
})
if zoneinfo != nil && *zoneinfo != "" {
if z, err := loadZoneFile(*zoneinfo, name); err == nil {
z.name = name
return z, nil
}

View File

@ -5,10 +5,36 @@
package time_test
import (
"fmt"
"os"
"testing"
"time"
)
func init() {
if time.ZoneinfoForTesting() != nil {
panic(fmt.Errorf("zoneinfo initialized before first LoadLocation"))
}
}
func TestEnvVarUsage(t *testing.T) {
time.ResetZoneinfoForTesting()
testZoneinfo := "foo.zip"
env := "ZONEINFO"
defer os.Setenv(env, os.Getenv(env))
os.Setenv(env, testZoneinfo)
// Result isn't important, we're testing the side effect of this command
time.LoadLocation("Asia/Jerusalem")
defer time.ResetZoneinfoForTesting()
if zoneinfo := time.ZoneinfoForTesting(); testZoneinfo != *zoneinfo {
t.Errorf("zoneinfo does not match env variable: got %q want %q", zoneinfo, testZoneinfo)
}
}
func TestVersion3(t *testing.T) {
time.ForceZipFileForTesting(true)
defer time.ForceZipFileForTesting(false)