...
Run Format

Source file src/time/genzabbrs.go

Documentation: time

  // 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.
  
  // +build ignore
  
  //
  // usage:
  //
  // go run genzabbrs.go -output zoneinfo_abbrs_windows.go
  //
  
  package main
  
  import (
  	"bytes"
  	"encoding/xml"
  	"flag"
  	"go/format"
  	"io/ioutil"
  	"log"
  	"net/http"
  	"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
  }
  
  type zones []*zone
  
  func (zs zones) Len() int           { return len(zs) }
  func (zs zones) Swap(i, j int)      { zs[i], zs[j] = zs[j], zs[i] }
  func (zs zones) Less(i, j int) bool { return zs[i].UnixName < zs[j].UnixName }
  
  const wzURL = "http://unicode.org/cldr/data/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() (zones, error) {
  	r, err := http.Get(wzURL)
  	if err != nil {
  		return nil, err
  	}
  	defer r.Body.Close()
  
  	data, err := ioutil.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(zones, 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.Sort(zs)
  	var v = struct {
  		URL string
  		Zs  zones
  	}{
  		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 = ioutil.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}}}
  
  `
  

View as plain text