forked from wcharczuk/go-chart
-
Notifications
You must be signed in to change notification settings - Fork 0
/
timeutil.go
150 lines (122 loc) · 3.5 KB
/
timeutil.go
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
149
150
package chart
import "time"
// SecondsPerXYZ
const (
SecondsPerHour = 60 * 60
SecondsPerDay = 60 * 60 * 24
)
// TimeMillis returns a duration as a float millis.
func TimeMillis(d time.Duration) float64 {
return float64(d) / float64(time.Millisecond)
}
// DiffHours returns the difference in hours between two times.
func DiffHours(t1, t2 time.Time) (hours int) {
t1n := t1.Unix()
t2n := t2.Unix()
var diff int64
if t1n > t2n {
diff = t1n - t2n
} else {
diff = t2n - t1n
}
return int(diff / (SecondsPerHour))
}
// TimeMin returns the minimum and maximum times in a given range.
func TimeMin(times ...time.Time) (min time.Time) {
if len(times) == 0 {
return
}
min = times[0]
for index := 1; index < len(times); index++ {
if times[index].Before(min) {
min = times[index]
}
}
return
}
// TimeMax returns the minimum and maximum times in a given range.
func TimeMax(times ...time.Time) (max time.Time) {
if len(times) == 0 {
return
}
max = times[0]
for index := 1; index < len(times); index++ {
if times[index].After(max) {
max = times[index]
}
}
return
}
// TimeMinMax returns the minimum and maximum times in a given range.
func TimeMinMax(times ...time.Time) (min, max time.Time) {
if len(times) == 0 {
return
}
min = times[0]
max = times[0]
for index := 1; index < len(times); index++ {
if times[index].Before(min) {
min = times[index]
}
if times[index].After(max) {
max = times[index]
}
}
return
}
// TimeToFloat64 returns a float64 representation of a time.
func TimeToFloat64(t time.Time) float64 {
return float64(t.UnixNano())
}
// TimeFromFloat64 returns a time from a float64.
func TimeFromFloat64(tf float64) time.Time {
return time.Unix(0, int64(tf))
}
// TimeDescending sorts a given list of times ascending, or min to max.
type TimeDescending []time.Time
// Len implements sort.Sorter
func (d TimeDescending) Len() int { return len(d) }
// Swap implements sort.Sorter
func (d TimeDescending) Swap(i, j int) { d[i], d[j] = d[j], d[i] }
// Less implements sort.Sorter
func (d TimeDescending) Less(i, j int) bool { return d[i].After(d[j]) }
// TimeAscending sorts a given list of times ascending, or min to max.
type TimeAscending []time.Time
// Len implements sort.Sorter
func (a TimeAscending) Len() int { return len(a) }
// Swap implements sort.Sorter
func (a TimeAscending) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
// Less implements sort.Sorter
func (a TimeAscending) Less(i, j int) bool { return a[i].Before(a[j]) }
// Days generates a seq of timestamps by day, from -days to today.
func Days(days int) []time.Time {
var values []time.Time
for day := days; day >= 0; day-- {
values = append(values, time.Now().AddDate(0, 0, -day))
}
return values
}
// Hours returns a sequence of times by the hour for a given number of hours
// after a given start.
func Hours(start time.Time, totalHours int) []time.Time {
times := make([]time.Time, totalHours)
last := start
for i := 0; i < totalHours; i++ {
times[i] = last
last = last.Add(time.Hour)
}
return times
}
// HoursFilled adds zero values for the data bounded by the start and end of the xdata array.
func HoursFilled(xdata []time.Time, ydata []float64) ([]time.Time, []float64) {
start, end := TimeMinMax(xdata...)
totalHours := DiffHours(start, end)
finalTimes := Hours(start, totalHours+1)
finalValues := make([]float64, totalHours+1)
var hoursFromStart int
for i, xd := range xdata {
hoursFromStart = DiffHours(start, xd)
finalValues[hoursFromStart] = ydata[i]
}
return finalTimes, finalValues
}