1// Copyright 2013 The Go Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style 3// license that can be found in the LICENSE file. 4 5// +build ignore 6 7// 8// usage: 9// 10// go run genzabbrs.go -output zoneinfo_abbrs_windows.go 11// 12 13package main 14 15import ( 16 "bytes" 17 "encoding/xml" 18 "flag" 19 "go/format" 20 "io/ioutil" 21 "log" 22 "net/http" 23 "sort" 24 "text/template" 25 "time" 26) 27 28var filename = flag.String("output", "zoneinfo_abbrs_windows.go", "output file name") 29 30// getAbbrs finds timezone abbreviations (standard and daylight saving time) 31// for location l. 32func getAbbrs(l *time.Location) (st, dt string) { 33 t := time.Date(time.Now().Year(), 0, 1, 0, 0, 0, 0, l) 34 abbr1, off1 := t.Zone() 35 for i := 0; i < 12; i++ { 36 t = t.AddDate(0, 1, 0) 37 abbr2, off2 := t.Zone() 38 if abbr1 != abbr2 { 39 if off2-off1 < 0 { // southern hemisphere 40 abbr1, abbr2 = abbr2, abbr1 41 } 42 return abbr1, abbr2 43 } 44 } 45 return abbr1, abbr1 46} 47 48type zone struct { 49 WinName string 50 UnixName string 51 StTime string 52 DSTime string 53} 54 55const wzURL = "http://unicode.org/cldr/data/common/supplemental/windowsZones.xml" 56 57type MapZone struct { 58 Other string `xml:"other,attr"` 59 Territory string `xml:"territory,attr"` 60 Type string `xml:"type,attr"` 61} 62 63type SupplementalData struct { 64 Zones []MapZone `xml:"windowsZones>mapTimezones>mapZone"` 65} 66 67func readWindowsZones() ([]*zone, error) { 68 r, err := http.Get(wzURL) 69 if err != nil { 70 return nil, err 71 } 72 defer r.Body.Close() 73 74 data, err := ioutil.ReadAll(r.Body) 75 if err != nil { 76 return nil, err 77 } 78 79 var sd SupplementalData 80 err = xml.Unmarshal(data, &sd) 81 if err != nil { 82 return nil, err 83 } 84 zs := make([]*zone, 0) 85 for _, z := range sd.Zones { 86 if z.Territory != "001" { 87 // to avoid dups. I don't know why. 88 continue 89 } 90 l, err := time.LoadLocation(z.Type) 91 if err != nil { 92 return nil, err 93 } 94 st, dt := getAbbrs(l) 95 zs = append(zs, &zone{ 96 WinName: z.Other, 97 UnixName: z.Type, 98 StTime: st, 99 DSTime: dt, 100 }) 101 } 102 return zs, nil 103} 104 105func main() { 106 flag.Parse() 107 zs, err := readWindowsZones() 108 if err != nil { 109 log.Fatal(err) 110 } 111 sort.Slice(zs, func(i, j int) bool { 112 return zs[i].UnixName < zs[j].UnixName 113 }) 114 var v = struct { 115 URL string 116 Zs []*zone 117 }{ 118 wzURL, 119 zs, 120 } 121 var buf bytes.Buffer 122 err = template.Must(template.New("prog").Parse(prog)).Execute(&buf, v) 123 if err != nil { 124 log.Fatal(err) 125 } 126 data, err := format.Source(buf.Bytes()) 127 if err != nil { 128 log.Fatal(err) 129 } 130 err = ioutil.WriteFile(*filename, data, 0644) 131 if err != nil { 132 log.Fatal(err) 133 } 134} 135 136const prog = ` 137// Copyright 2013 The Go Authors. All rights reserved. 138// Use of this source code is governed by a BSD-style 139// license that can be found in the LICENSE file. 140 141// Code generated by genzabbrs.go; DO NOT EDIT. 142// Based on information from {{.URL}} 143 144package time 145 146type abbr struct { 147 std string 148 dst string 149} 150 151var abbrs = map[string]abbr{ 152{{range .Zs}} "{{.WinName}}": {"{{.StTime}}", "{{.DSTime}}"}, // {{.UnixName}} 153{{end}}} 154 155` 156