aboutsummaryrefslogtreecommitdiff
path: root/src/time/zoneinfo_read.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/time/zoneinfo_read.go')
-rw-r--r--src/time/zoneinfo_read.go44
1 files changed, 27 insertions, 17 deletions
diff --git a/src/time/zoneinfo_read.go b/src/time/zoneinfo_read.go
index 22a60f3211..f7fe59c385 100644
--- a/src/time/zoneinfo_read.go
+++ b/src/time/zoneinfo_read.go
@@ -247,8 +247,8 @@ func LoadLocationFromTZData(name string, data []byte) (*Location, error) {
// This also avoids a panic later when we add and then use a fake transition (golang.org/issue/29437).
return nil, badData
}
- zone := make([]zone, nzone)
- for i := range zone {
+ zones := make([]zone, nzone)
+ for i := range zones {
var ok bool
var n uint32
if n, ok = zonedata.big4(); !ok {
@@ -257,22 +257,22 @@ func LoadLocationFromTZData(name string, data []byte) (*Location, error) {
if uint32(int(n)) != n {
return nil, badData
}
- zone[i].offset = int(int32(n))
+ zones[i].offset = int(int32(n))
var b byte
if b, ok = zonedata.byte(); !ok {
return nil, badData
}
- zone[i].isDST = b != 0
+ zones[i].isDST = b != 0
if b, ok = zonedata.byte(); !ok || int(b) >= len(abbrev) {
return nil, badData
}
- zone[i].name = byteString(abbrev[b:])
+ zones[i].name = byteString(abbrev[b:])
if runtime.GOOS == "aix" && len(name) > 8 && (name[:8] == "Etc/GMT+" || name[:8] == "Etc/GMT-") {
// There is a bug with AIX 7.2 TL 0 with files in Etc,
// GMT+1 will return GMT-1 instead of GMT+1 or -01.
if name != "Etc/GMT+0" {
// GMT+0 is OK
- zone[i].name = name[4:]
+ zones[i].name = name[4:]
}
}
}
@@ -295,7 +295,7 @@ func LoadLocationFromTZData(name string, data []byte) (*Location, error) {
}
}
tx[i].when = n
- if int(txzones[i]) >= len(zone) {
+ if int(txzones[i]) >= len(zones) {
return nil, badData
}
tx[i].index = txzones[i]
@@ -314,7 +314,7 @@ func LoadLocationFromTZData(name string, data []byte) (*Location, error) {
}
// Committed to succeed.
- l := &Location{zone: zone, tx: tx, name: name, extend: extend}
+ l := &Location{zone: zones, tx: tx, name: name, extend: extend}
// Fill in the cache with information about right now,
// since that will be the most common lookup.
@@ -323,26 +323,27 @@ func LoadLocationFromTZData(name string, data []byte) (*Location, error) {
if tx[i].when <= sec && (i+1 == len(tx) || sec < tx[i+1].when) {
l.cacheStart = tx[i].when
l.cacheEnd = omega
- zoneIdx := tx[i].index
+ l.cacheZone = &l.zone[tx[i].index]
if i+1 < len(tx) {
l.cacheEnd = tx[i+1].when
} else if l.extend != "" {
// If we're at the end of the known zone transitions,
// try the extend string.
- if name, _, estart, eend, ok := tzset(l.extend, l.cacheEnd, sec); ok {
+ if name, offset, estart, eend, isDST, ok := tzset(l.extend, l.cacheEnd, sec); ok {
l.cacheStart = estart
l.cacheEnd = eend
- // Find the zone that is returned by tzset,
- // the last transition is not always the correct zone.
- for i, z := range l.zone {
- if z.name == name {
- zoneIdx = uint8(i)
- break
+ // Find the zone that is returned by tzset to avoid allocation if possible.
+ if zoneIdx := findZone(l.zone, name, offset, isDST); zoneIdx != -1 {
+ l.cacheZone = &l.zone[zoneIdx]
+ } else {
+ l.cacheZone = &zone{
+ name: name,
+ offset: offset,
+ isDST: isDST,
}
}
}
}
- l.cacheZone = &l.zone[zoneIdx]
break
}
}
@@ -350,6 +351,15 @@ func LoadLocationFromTZData(name string, data []byte) (*Location, error) {
return l, nil
}
+func findZone(zones []zone, name string, offset int, isDST bool) int {
+ for i, z := range zones {
+ if z.name == name && z.offset == offset && z.isDST == isDST {
+ return i
+ }
+ }
+ return -1
+}
+
// loadTzinfoFromDirOrZip returns the contents of the file with the given name
// in dir. dir can either be an uncompressed zip file, or a directory.
func loadTzinfoFromDirOrZip(dir, name string) ([]byte, error) {