diff --git a/model/time.go b/model/time.go index 46259b1f..7b0064fd 100644 --- a/model/time.go +++ b/model/time.go @@ -150,7 +150,13 @@ func (t *Time) UnmarshalJSON(b []byte) error { return err } - *t = Time(v + va) + // If the value was something like -0.1 the negative is lost in the + // parsing because of the leading zero, this ensures that we capture it. + if len(p[0]) > 0 && p[0][0] == '-' && v+va > 0 { + *t = Time(v+va) * -1 + } else { + *t = Time(v + va) + } default: return fmt.Errorf("invalid time %q", string(b)) diff --git a/model/time_test.go b/model/time_test.go index 3efdd65f..315bc4e5 100644 --- a/model/time_test.go +++ b/model/time_test.go @@ -14,6 +14,7 @@ package model import ( + "strconv" "testing" "time" ) @@ -130,3 +131,37 @@ func TestParseDuration(t *testing.T) { } } } + +func TestTimeJSON(t *testing.T) { + tests := []struct { + in Time + out string + }{ + {Time(1), `0.001`}, + {Time(-1), `-0.001`}, + } + + for i, test := range tests { + t.Run(strconv.Itoa(i), func(t *testing.T) { + b, err := test.in.MarshalJSON() + if err != nil { + t.Fatalf("Error marshaling time: %v", err) + } + + if string(b) != test.out { + t.Errorf("Mismatch in marshal expected=%s actual=%s", test.out, b) + } + + var tm Time + if err := tm.UnmarshalJSON(b); err != nil { + t.Fatalf("Error Unmarshaling time: %v", err) + } + + if !test.in.Equal(tm) { + t.Fatalf("Mismatch after Unmarshal expected=%v actual=%v", test.in, tm) + } + + }) + } + +}