File: generate.go

package info (click to toggle)
golang-github-cactus-tai64 1.0.3-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 96 kB
  • sloc: makefile: 5
file content (148 lines) | stat: -rw-r--r-- 2,888 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
// Copyright (c) 2012-2016 Eli Janssen
// Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file.

package main

import (
	"bufio"
	"bytes"
	"flag"
	"fmt"
	"go/format"
	"html/template"
	"log"
	"net/http"
	"os"
	"path"
	"strconv"
	"strings"
	"time"
)

const tplText = `
// Copyright (c) 2012-2016 Eli Janssen
// Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file.

// THIS FILE IS AUTOGENERATED. DO NOT EDIT!

package {{.Pkg}}

// https://hpiers.obspm.fr/iers/bul/bulc/Leap_Second.dat
// http://www.stjarnhimlen.se/comp/time.html
var tia64nDifferences = []struct {
    // TAI time
    ttime int64
    // TAI-UTC offset
	offset int64
    // unix UTC time
	utime int64
}{
	{{- range .Entries}}
	{{"{"}}0x{{.Tts|printf "%x"}}, {{.Drift}}, {{.Ts}}{{"}"}}, // {{.TsD}}
	{{- end}}
}

var tia64nSize = len(tia64nDifferences)
`

type srcFile struct {
	Pkg     string
	Entries []entry
}

type entry struct {
	Ts    int64
	TsD   string
	Drift int64
	Tts   int64
}

const datURL = "https://hpiers.obspm.fr/iers/bul/bulc/Leap_Second.dat"

func main() {
	var output, pkg string
	flag.StringVar(&output, "output", "", "output file")
	flag.StringVar(&pkg, "pkg", "", "package name")
	flag.Parse()

	if output == "" {
		log.Fatal("Output option is required")
	}

	if pkg == "" {
		log.Fatal("Package option is required")
	}

	var br *bufio.Reader
	resp, err := http.Get(datURL)
	if err != nil {
		log.Fatalf("Error fetching '%s': %s", datURL, err)
	}
	defer resp.Body.Close()
	br = bufio.NewReader(resp.Body)

	fmt.Printf("Generating '%s' based on '%s'\n", path.Base(output), datURL)

	t, err := template.New("fileTemplate").Parse(strings.TrimLeft(tplText, "\n"))
	if err != nil {
		log.Fatal(err)
	}

	entries := make([]entry, 0)

	for {
		line, err := br.ReadString('\n')
		if err != nil {
			break
		}

		line = strings.TrimSpace(line)
		if line == "" || strings.HasPrefix(line, ";") || strings.HasPrefix(line, "#") {
			continue
		}

		parts := strings.Fields(line)
		// parse date of leap second
		t, err := time.Parse("2-1-2006", strings.Join(parts[1:4], "-"))
		if err != nil {
			fmt.Println(err)
			continue
		}

		if t.Before(time.Date(1972, 1, 1, 0, 0, 0, 0, time.UTC)) {
			continue
		}

		// parse TAI-UTC(s)
		s, err := strconv.ParseFloat(parts[4], 32)
		if err != nil {
			fmt.Println(err)
			continue
		}
		// just truncate the float to int
		unixT := t.Unix()
		taiT := (2 << 61) + unixT + int64(s)
		e := entry{unixT, t.Format(time.RFC3339), int64(s), taiT}
		entries = append(entries, e)
	}

	bufr := &bytes.Buffer{}

	srcfile := &srcFile{pkg, entries}
	err = t.Execute(bufr, srcfile)
	if err != nil {
		log.Fatal(err)
	}

	outBytes, err := format.Source(bufr.Bytes())
	if err != nil {
		log.Fatal(err)
	}

	err = os.WriteFile(output, outBytes, 0644)
	if err != nil {
		log.Fatal(err)
	}
}