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