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.go34
1 files changed, 32 insertions, 2 deletions
diff --git a/src/time/zoneinfo_read.go b/src/time/zoneinfo_read.go
index 1e559a62cc..698427b779 100644
--- a/src/time/zoneinfo_read.go
+++ b/src/time/zoneinfo_read.go
@@ -78,6 +78,13 @@ func (d *dataIO) byte() (n byte, ok bool) {
return p[0], true
}
+// read returns the read of the data in the buffer.
+func (d *dataIO) rest() []byte {
+ r := d.p
+ d.p = nil
+ return r
+}
+
// Make a string by stopping at the first NUL
func byteString(p []byte) string {
for i := 0; i < len(p); i++ {
@@ -213,6 +220,12 @@ func LoadLocationFromTZData(name string, data []byte) (*Location, error) {
return nil, badData
}
+ var extend string
+ rest := d.rest()
+ if len(rest) > 2 && rest[0] == '\n' && rest[len(rest)-1] == '\n' {
+ extend = string(rest[1 : len(rest)-1])
+ }
+
// Now we can build up a useful data structure.
// First the zone information.
// utcoff[4] isdst[1] nameindex[1]
@@ -289,7 +302,7 @@ func LoadLocationFromTZData(name string, data []byte) (*Location, error) {
}
// Committed to succeed.
- l := &Location{zone: zone, tx: tx, name: name}
+ l := &Location{zone: zone, tx: tx, name: name, extend: extend}
// Fill in the cache with information about right now,
// since that will be the most common lookup.
@@ -298,10 +311,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
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 {
+ 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
+ }
+ }
+ }
}
- l.cacheZone = &l.zone[tx[i].index]
+ l.cacheZone = &l.zone[zoneIdx]
+ break
}
}