fix rounding of time to milliseconds (#5352)

Current implementation of RoundToMilliseconds is broken due to improper handling of floating point operation in go.
Fixing it by using simple division and modulo operators
pull/5355/head
Sandeep Sukhani 4 years ago committed by GitHub
parent 8e9009a7e3
commit 0afd113c96
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 12
      pkg/util/conv.go
  2. 14
      pkg/util/conv_test.go

@ -1,7 +1,6 @@
package util
import (
"math"
"time"
"unsafe"
@ -28,8 +27,15 @@ func MapToModelLabelSet(m map[string]string) model.LabelSet {
// RoundToMilliseconds returns milliseconds precision time from nanoseconds.
// from will be rounded down to the nearest milliseconds while through is rounded up.
func RoundToMilliseconds(from, through time.Time) (model.Time, model.Time) {
return model.Time(int64(math.Floor(float64(from.UnixNano()) / float64(time.Millisecond)))),
model.Time(int64(math.Ceil(float64(through.UnixNano()) / float64(time.Millisecond))))
fromMs := from.UnixNano() / int64(time.Millisecond)
throughMs := through.UnixNano() / int64(time.Millisecond)
// add a millisecond to the through time if the nanosecond offset within the second is not a multiple of milliseconds
if int64(through.Nanosecond())%int64(time.Millisecond) != 0 {
throughMs++
}
return model.Time(fromMs), model.Time(throughMs)
}
// LabelsToMetric converts a Labels to Metric

@ -44,6 +44,20 @@ func TestRoundToMilliseconds(t *testing.T) {
model.Time(1),
model.Time(3),
},
{
"rounding large number in nanoseconds",
time.Unix(0, 1643958368442000064),
time.Unix(0, 1643958368443000064),
model.Time(1643958368442),
model.Time(1643958368444),
},
{
"already rounded large number in nanoseconds",
time.Unix(0, 1643958368442000000),
time.Unix(0, 1643958368443000000),
model.Time(1643958368442),
model.Time(1643958368443),
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {

Loading…
Cancel
Save