Skip to content

Commit

Permalink
fix: incorrect parsing of UNIX nanoseconds
Browse files Browse the repository at this point in the history
  • Loading branch information
ssgreg committed Oct 24, 2018
1 parent d6d7e34 commit 2dd850c
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 17 deletions.
34 changes: 17 additions & 17 deletions time_parse.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package humanlog

import (
"math"
"time"
)

Expand All @@ -24,18 +23,19 @@ var formats = []string{
time.StampNano,
}

func parseTimeFloat64(value float64) (time.Time, bool) {
if value/math.Pow10(15) > 1 { // Nanoseconds
secs := int64(math.Trunc(value / math.Pow10(6)))
nsecs := int64(math.Mod(value, math.Pow10(6)))
return time.Unix(secs, nsecs), true
} else if value/math.Pow10(12) > 1 { // Milliseconds
secs := int64(math.Trunc(value / math.Pow10(3)))
nsecs := int64(math.Mod(value, math.Pow10(3))) * int64(math.Pow10(3))
return time.Unix(secs, nsecs), true
} else {
return time.Unix(int64(value), 0), true
func parseTimeFloat64(value float64) time.Time {
v := int64(value)
switch {
case v > 1e18:
case v > 1e15:
v *= 1e3
case v > 1e12:
v *= 1e6
default:
return time.Unix(v, 0)
}

return time.Unix(v/1e9, v%1e9)
}

// tries to parse time using a couple of formats before giving up
Expand All @@ -51,15 +51,15 @@ func tryParseTime(value interface{}) (time.Time, bool) {
}
}
case float32:
return parseTimeFloat64(float64(value.(float32)))
return parseTimeFloat64(float64(value.(float32))), true
case float64:
return parseTimeFloat64(value.(float64))
return parseTimeFloat64(value.(float64)), true
case int:
return parseTimeFloat64(float64(value.(int)))
return parseTimeFloat64(float64(value.(int))), true
case int32:
return parseTimeFloat64(float64(value.(int32)))
return parseTimeFloat64(float64(value.(int32))), true
case int64:
return parseTimeFloat64(float64(value.(int64)))
return parseTimeFloat64(float64(value.(int64))), true
}
return t, false
}
36 changes: 36 additions & 0 deletions time_parse_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package humanlog

import (
"testing"
)

func TestTimeParseFloat64(t *testing.T) {
t.Run("nanoseconds", func(t *testing.T) {
golden := float64(1540369190466951764)
tm := parseTimeFloat64(golden)
if int64(golden) != tm.UnixNano() {
t.Fatal(tm.UnixNano())
}
})
t.Run("microseconds", func(t *testing.T) {
golden := float64(1540369190466951)
tm := parseTimeFloat64(golden)
if int64(golden)*1e3 != tm.UnixNano() {
t.Fatal(tm.UnixNano())
}
})
t.Run("milliseconds", func(t *testing.T) {
golden := float64(1540369190466)
tm := parseTimeFloat64(golden)
if int64(golden)*1e6 != tm.UnixNano() {
t.Fatal(tm.UnixNano())
}
})
t.Run("seconds", func(t *testing.T) {
golden := float64(1540369190)
tm := parseTimeFloat64(golden)
if int64(golden)*1e9 != tm.UnixNano() {
t.Fatal(tm.UnixNano())
}
})
}

0 comments on commit 2dd850c

Please sign in to comment.