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 { if t.IsZero() { return 0 } return float64(t.UnixNano()) } // TimeFromFloat64 returns a time in nanosecond from a float64. func TimeFromFloat64(tf float64) time.Time { if tf == 0 { return 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 }