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 "slices"
25 "strings"
26 "text/template"
27 "time"
28 )
29
30 var filename = flag.String("output", "zoneinfo_abbrs_windows.go", "output file name")
31
32
33
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 {
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/main/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
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 slices.SortFunc(zs, func(a, b *zone) int {
114 return strings.Compare(a.UnixName, b.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 `
158
View as plain text