| // Copyright 2013 The Go Authors. All rights reserved. | 
 | // Use of this source code is governed by a BSD-style | 
 | // license that can be found in the LICENSE file. | 
 |  | 
 | // +build ignore | 
 |  | 
 | // | 
 | // usage: | 
 | // | 
 | // go run genzabbrs.go -output zoneinfo_abbrs_windows.go | 
 | // | 
 |  | 
 | package main | 
 |  | 
 | import ( | 
 | 	"bytes" | 
 | 	"encoding/xml" | 
 | 	"flag" | 
 | 	"go/format" | 
 | 	"io/ioutil" | 
 | 	"log" | 
 | 	"net/http" | 
 | 	"sort" | 
 | 	"text/template" | 
 | 	"time" | 
 | ) | 
 |  | 
 | var filename = flag.String("output", "zoneinfo_abbrs_windows.go", "output file name") | 
 |  | 
 | // getAbbrs finds timezone abbreviations (standard and daylight saving time) | 
 | // for location l. | 
 | func getAbbrs(l *time.Location) (st, dt string) { | 
 | 	t := time.Date(time.Now().Year(), 0, 0, 0, 0, 0, 0, l) | 
 | 	abbr1, off1 := t.Zone() | 
 | 	for i := 0; i < 12; i++ { | 
 | 		t = t.AddDate(0, 1, 0) | 
 | 		abbr2, off2 := t.Zone() | 
 | 		if abbr1 != abbr2 { | 
 | 			if off2-off1 < 0 { // southern hemisphere | 
 | 				abbr1, abbr2 = abbr2, abbr1 | 
 | 			} | 
 | 			return abbr1, abbr2 | 
 | 		} | 
 | 	} | 
 | 	return abbr1, abbr1 | 
 | } | 
 |  | 
 | type zone struct { | 
 | 	WinName  string | 
 | 	UnixName string | 
 | 	StTime   string | 
 | 	DSTime   string | 
 | } | 
 |  | 
 | type zones []*zone | 
 |  | 
 | func (zs zones) Len() int           { return len(zs) } | 
 | func (zs zones) Swap(i, j int)      { zs[i], zs[j] = zs[j], zs[i] } | 
 | func (zs zones) Less(i, j int) bool { return zs[i].UnixName < zs[j].UnixName } | 
 |  | 
 | const wzURL = "http://unicode.org/cldr/data/common/supplemental/windowsZones.xml" | 
 |  | 
 | type MapZone struct { | 
 | 	Other     string `xml:"other,attr"` | 
 | 	Territory string `xml:"territory,attr"` | 
 | 	Type      string `xml:"type,attr"` | 
 | } | 
 |  | 
 | type SupplementalData struct { | 
 | 	Zones []MapZone `xml:"windowsZones>mapTimezones>mapZone"` | 
 | } | 
 |  | 
 | func readWindowsZones() (zones, error) { | 
 | 	r, err := http.Get(wzURL) | 
 | 	if err != nil { | 
 | 		return nil, err | 
 | 	} | 
 | 	defer r.Body.Close() | 
 |  | 
 | 	data, err := ioutil.ReadAll(r.Body) | 
 | 	if err != nil { | 
 | 		return nil, err | 
 | 	} | 
 |  | 
 | 	var sd SupplementalData | 
 | 	err = xml.Unmarshal(data, &sd) | 
 | 	if err != nil { | 
 | 		return nil, err | 
 | 	} | 
 | 	zs := make(zones, 0) | 
 | 	for _, z := range sd.Zones { | 
 | 		if z.Territory != "001" { | 
 | 			// to avoid dups. I don't know why. | 
 | 			continue | 
 | 		} | 
 | 		l, err := time.LoadLocation(z.Type) | 
 | 		if err != nil { | 
 | 			return nil, err | 
 | 		} | 
 | 		st, dt := getAbbrs(l) | 
 | 		zs = append(zs, &zone{ | 
 | 			WinName:  z.Other, | 
 | 			UnixName: z.Type, | 
 | 			StTime:   st, | 
 | 			DSTime:   dt, | 
 | 		}) | 
 | 	} | 
 | 	return zs, nil | 
 | } | 
 |  | 
 | func main() { | 
 | 	flag.Parse() | 
 | 	zs, err := readWindowsZones() | 
 | 	if err != nil { | 
 | 		log.Fatal(err) | 
 | 	} | 
 | 	sort.Sort(zs) | 
 | 	var v = struct { | 
 | 		URL string | 
 | 		Zs  zones | 
 | 	}{ | 
 | 		wzURL, | 
 | 		zs, | 
 | 	} | 
 | 	var buf bytes.Buffer | 
 | 	err = template.Must(template.New("prog").Parse(prog)).Execute(&buf, v) | 
 | 	if err != nil { | 
 | 		log.Fatal(err) | 
 | 	} | 
 | 	data, err := format.Source(buf.Bytes()) | 
 | 	if err != nil { | 
 | 		log.Fatal(err) | 
 | 	} | 
 | 	err = ioutil.WriteFile(*filename, data, 0644) | 
 | 	if err != nil { | 
 | 		log.Fatal(err) | 
 | 	} | 
 | } | 
 |  | 
 | const prog = ` | 
 | // Copyright 2013 The Go Authors. All rights reserved. | 
 | // Use of this source code is governed by a BSD-style | 
 | // license that can be found in the LICENSE file. | 
 |  | 
 | // generated by genzabbrs.go from | 
 | // {{.URL}} | 
 |  | 
 | package time | 
 |  | 
 | type abbr struct { | 
 | 	std string | 
 | 	dst string | 
 | } | 
 |  | 
 | var abbrs = map[string]abbr{ | 
 | {{range .Zs}}	"{{.WinName}}": {"{{.StTime}}", "{{.DSTime}}"}, // {{.UnixName}} | 
 | {{end}}} | 
 |  | 
 | ` |