time: deal a bit better with time zones in Parse

* Document Parse's zone interpretation.
* Add ParseInLocation (API change).
* Recognize "wrong" time zone names, like daylight savings time in winter.
* Disambiguate time zone names using offset (like winter EST vs summer EST in Sydney).

The final two are backwards-incompatible changes, but I believe
they are both buggy behavior in the Go 1.0 versions; the old results
were more wrong than the new ones.

Fixes #3604.
Fixes #3653.
Fixes #4001.

R=adg
CC=golang-dev
https://golang.org/cl/7288052
diff --git a/src/pkg/time/zoneinfo.go b/src/pkg/time/zoneinfo.go
index 116d343..c44477f 100644
--- a/src/pkg/time/zoneinfo.go
+++ b/src/pkg/time/zoneinfo.go
@@ -145,15 +145,36 @@
 }
 
 // lookupName returns information about the time zone with
-// the given name (such as "EST").
-func (l *Location) lookupName(name string) (offset int, isDST bool, ok bool) {
+// the given name (such as "EST") at the given pseudo-Unix time
+// (what the given time of day would be in UTC).
+func (l *Location) lookupName(name string, unix int64) (offset int, isDST bool, ok bool) {
 	l = l.get()
+
+	// First try for a zone with the right name that was actually
+	// in effect at the given time. (In Sydney, Australia, both standard
+	// and daylight-savings time are abbreviated "EST". Using the
+	// offset helps us pick the right one for the given time.
+	// It's not perfect: during the backward transition we might pick
+	// either one.)
+	for i := range l.zone {
+		zone := &l.zone[i]
+		if zone.name == name {
+			nam, offset, isDST, _, _ := l.lookup(unix - int64(zone.offset))
+			if nam == zone.name {
+				return offset, isDST, true
+			}
+		}
+	}
+
+	// Otherwise fall back to an ordinary name match.
 	for i := range l.zone {
 		zone := &l.zone[i]
 		if zone.name == name {
 			return zone.offset, zone.isDST, true
 		}
 	}
+
+	// Otherwise, give up.
 	return
 }