]> Cypherpunks repositories - gostls13.git/commitdiff
time: enable Location loading from user provided timezone data
authorFlorian Uekermann <florian@uekermann.me>
Fri, 6 Oct 2017 15:16:43 +0000 (17:16 +0200)
committerBrad Fitzpatrick <bradfitz@golang.org>
Tue, 21 Nov 2017 19:13:52 +0000 (19:13 +0000)
The return values of the LoadLocation are inherently dependent
on the runtime environment. Add LoadLocationFromTZData, whose
results depend only on the timezone data provided as arguments.

Fixes #20629

Change-Id: I43b181f4c05c219be3ec57327540263b7cb3b2aa
Reviewed-on: https://go-review.googlesource.com/68890
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
src/time/export_test.go
src/time/internal_test.go
src/time/zoneinfo.go
src/time/zoneinfo_read.go
src/time/zoneinfo_test.go

index 4c08ab13afc27276d76d9b08c268683eb686d1fa..ae24ceb99abd580c7d1512b7ad8a96b47bf471db 100644 (file)
@@ -34,4 +34,5 @@ var (
        GetMono                = (*Time).mono
        ErrLocation            = errLocation
        ReadFile               = readFile
+       LoadTzinfo             = loadTzinfo
 )
index 07ebe5e03d7e2f56597ebf0ceb9b7d8009da18db..76d55241241dacc50bea742dff4da65ef6cc637c 100644 (file)
@@ -18,11 +18,11 @@ func initTestingZone() {
        localLoc = *z
 }
 
-var origZoneSources = zoneSources
+var OrigZoneSources = zoneSources
 
 func forceZipFileForTesting(zipOnly bool) {
-       zoneSources = make([]string, len(origZoneSources))
-       copy(zoneSources, origZoneSources)
+       zoneSources = make([]string, len(OrigZoneSources))
+       copy(zoneSources, OrigZoneSources)
        if zipOnly {
                zoneSources = zoneSources[len(zoneSources)-1:]
        }
index 4424b4410687760b193f56d073f57d93d7bce473..96ff8d39708f5948473029387eee867e7c9eb703 100644 (file)
@@ -294,7 +294,7 @@ func LoadLocation(name string) (*Location, error) {
        })
        if *zoneinfo != "" {
                if zoneData, err := loadTzinfoFromDirOrZip(*zoneinfo, name); err == nil {
-                       if z, err := newLocationFromTzinfo(name, zoneData); err == nil {
+                       if z, err := LoadLocationFromTZData(name, zoneData); err == nil {
                                return z, nil
                        }
                }
index 6fdcc1a2a8628cabb401345273aa508c09cba0d2..839b37aac4e4d31a1aff8967ee261ac9c5284bc6 100644 (file)
@@ -79,11 +79,12 @@ func byteString(p []byte) string {
 
 var badData = errors.New("malformed time zone information")
 
-// newLocationFromTzinfo returns the Location described by Tzinfo with the given name.
-// The expected format for Tzinfo is that of a timezone file as they are found in the
-// the IANA Time Zone database.
-func newLocationFromTzinfo(name string, Tzinfo []byte) (*Location, error) {
-       d := dataIO{Tzinfo, false}
+// LoadLocationFromTZData returns a Location with the given name
+// initialized from the IANA Time Zone database-formatted data.
+// The data should be in the format of a standard IANA time zone file
+// (for example, the content of /etc/localtime on Unix systems).
+func LoadLocationFromTZData(name string, data []byte) (*Location, error) {
+       d := dataIO{data, false}
 
        // 4-byte magic "TZif"
        if magic := d.read(4); string(magic) != "TZif" {
@@ -390,7 +391,7 @@ func loadLocation(name string, sources []string) (z *Location, firstErr error) {
        for _, source := range sources {
                var zoneData, err = loadTzinfo(name, source)
                if err == nil {
-                       if z, err = newLocationFromTzinfo(name, zoneData); err == nil {
+                       if z, err = LoadLocationFromTZData(name, zoneData); err == nil {
                                return z, nil
                        }
                }
index 452262f2caf499eae3b3ec3a327377925a8e101b..b9455db025a8b317d20e853d0472f304eb1fc81e 100644 (file)
@@ -7,6 +7,7 @@ package time_test
 import (
        "fmt"
        "os"
+       "reflect"
        "testing"
        "time"
 )
@@ -116,3 +117,27 @@ func TestLocationNames(t *testing.T) {
                t.Errorf(`invalid UTC location name: got %q want "UTC"`, time.UTC)
        }
 }
+
+func TestLoadLocationFromTzinfo(t *testing.T) {
+       time.ForceZipFileForTesting(true)
+       defer time.ForceZipFileForTesting(false)
+
+       const locationName = "Asia/Jerusalem"
+       reference, err := time.LoadLocation(locationName)
+       if err != nil {
+               t.Fatal(err)
+       }
+
+       tzinfo, err := time.LoadTzinfo(locationName, time.OrigZoneSources[len(time.OrigZoneSources)-1])
+       if err != nil {
+               t.Fatal(err)
+       }
+       sample, err := time.LoadLocationFromTZData(locationName, tzinfo)
+       if err != nil {
+               t.Fatal(err)
+       }
+
+       if !reflect.DeepEqual(reference, sample) {
+               t.Errorf("return values of LoadLocationFromTZData and LoadLocation don't match")
+       }
+}