diff options
Diffstat (limited to 'src/time/genzabbrs.go')
-rw-r--r-- | src/time/genzabbrs.go | 156 |
1 files changed, 156 insertions, 0 deletions
diff --git a/src/time/genzabbrs.go b/src/time/genzabbrs.go new file mode 100644 index 0000000..7dbd22f --- /dev/null +++ b/src/time/genzabbrs.go @@ -0,0 +1,156 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build ignore + +// +// usage: +// +// go run genzabbrs.go -output zoneinfo_abbrs_windows.go +// + +package main + +import ( + "bytes" + "encoding/xml" + "flag" + "go/format" + "io" + "log" + "net/http" + "os" + "sort" + "text/template" + "time" +) + +var filename = flag.String("output", "zoneinfo_abbrs_windows.go", "output file name") + +// getAbbrs finds timezone abbreviations (standard and daylight saving time) +// for location l. +func getAbbrs(l *time.Location) (st, dt string) { + t := time.Date(time.Now().Year(), 0, 1, 0, 0, 0, 0, l) + abbr1, off1 := t.Zone() + for i := 0; i < 12; i++ { + t = t.AddDate(0, 1, 0) + abbr2, off2 := t.Zone() + if abbr1 != abbr2 { + if off2-off1 < 0 { // southern hemisphere + abbr1, abbr2 = abbr2, abbr1 + } + return abbr1, abbr2 + } + } + return abbr1, abbr1 +} + +type zone struct { + WinName string + UnixName string + StTime string + DSTime string +} + +const wzURL = "https://raw.githubusercontent.com/unicode-org/cldr/main/common/supplemental/windowsZones.xml" + +type MapZone struct { + Other string `xml:"other,attr"` + Territory string `xml:"territory,attr"` + Type string `xml:"type,attr"` +} + +type SupplementalData struct { + Zones []MapZone `xml:"windowsZones>mapTimezones>mapZone"` +} + +func readWindowsZones() ([]*zone, error) { + r, err := http.Get(wzURL) + if err != nil { + return nil, err + } + defer r.Body.Close() + + data, err := io.ReadAll(r.Body) + if err != nil { + return nil, err + } + + var sd SupplementalData + err = xml.Unmarshal(data, &sd) + if err != nil { + return nil, err + } + zs := make([]*zone, 0) + for _, z := range sd.Zones { + if z.Territory != "001" { + // to avoid dups. I don't know why. + continue + } + l, err := time.LoadLocation(z.Type) + if err != nil { + return nil, err + } + st, dt := getAbbrs(l) + zs = append(zs, &zone{ + WinName: z.Other, + UnixName: z.Type, + StTime: st, + DSTime: dt, + }) + } + return zs, nil +} + +func main() { + flag.Parse() + zs, err := readWindowsZones() + if err != nil { + log.Fatal(err) + } + sort.Slice(zs, func(i, j int) bool { + return zs[i].UnixName < zs[j].UnixName + }) + var v = struct { + URL string + Zs []*zone + }{ + wzURL, + zs, + } + var buf bytes.Buffer + err = template.Must(template.New("prog").Parse(prog)).Execute(&buf, v) + if err != nil { + log.Fatal(err) + } + data, err := format.Source(buf.Bytes()) + if err != nil { + log.Fatal(err) + } + err = os.WriteFile(*filename, data, 0644) + if err != nil { + log.Fatal(err) + } +} + +const prog = ` +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Code generated by genzabbrs.go; DO NOT EDIT. +// Based on information from {{.URL}} + +package time + +type abbr struct { + std string + dst string +} + +var abbrs = map[string]abbr{ +{{range .Zs}} "{{.WinName}}": {"{{.StTime}}", "{{.DSTime}}"}, // {{.UnixName}} +{{end}}} + +` |