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