github.com/epfl-dcsl/gotee@v0.0.0-20200909122901-014b35f5e5e9/src/time/genzabbrs.go (about) 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 13 package main 14 15 import ( 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 28 var 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. 32 func 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 48 type zone struct { 49 WinName string 50 UnixName string 51 StTime string 52 DSTime string 53 } 54 55 const wzURL = "http://unicode.org/cldr/data/common/supplemental/windowsZones.xml" 56 57 type MapZone struct { 58 Other string `xml:"other,attr"` 59 Territory string `xml:"territory,attr"` 60 Type string `xml:"type,attr"` 61 } 62 63 type SupplementalData struct { 64 Zones []MapZone `xml:"windowsZones>mapTimezones>mapZone"` 65 } 66 67 func 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 105 func 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 136 const 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 144 package time 145 146 type abbr struct { 147 std string 148 dst string 149 } 150 151 var abbrs = map[string]abbr{ 152 {{range .Zs}} "{{.WinName}}": {"{{.StTime}}", "{{.DSTime}}"}, // {{.UnixName}} 153 {{end}}} 154 155 `