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