Source file src/time/genzabbrs.go

     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  
     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"
    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  // getAbbrs finds timezone abbreviations (standard and daylight saving time)
    32  // for location l.
    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 { // southern hemisphere
    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/main/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  			// to avoid dups. I don't know why.
    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