Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 17 additions & 23 deletions model/time.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,44 +123,38 @@ func (t Time) MarshalJSON() ([]byte, error) {

// UnmarshalJSON implements the json.Unmarshaler interface.
func (t *Time) UnmarshalJSON(b []byte) error {
p := strings.Split(string(b), ".")
switch len(p) {
case 1:
v, err := strconv.ParseInt(p[0], 10, 64)
base, frac, found := strings.Cut(string(b), ".")
if !found {
v, err := strconv.ParseInt(base, 10, 64)
if err != nil {
return err
}
*t = Time(v * second)

case 2:
v, err := strconv.ParseInt(p[0], 10, 64)
} else {
v, err := strconv.ParseInt(base, 10, 64)
if err != nil {
return err
}
v *= second

prec := dotPrecision - len(p[1])
prec := dotPrecision - len(frac)
if prec < 0 {
p[1] = p[1][:dotPrecision]
} else if prec > 0 {
p[1] += strings.Repeat("0", prec)
frac = frac[:dotPrecision]
}

va, err := strconv.ParseInt(p[1], 10, 32)
va, err := strconv.ParseInt(frac, 10, 32)
if err != nil {
return err
}

// 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)
switch prec {
case 1:
va *= 10
case 2:
va *= 100
}

default:
return fmt.Errorf("invalid time %q", string(b))
if len(base) > 0 && base[0] == '-' {
va = -va
}
*t = Time(v*second + va)
}
return nil
}
Expand Down
19 changes: 19 additions & 0 deletions model/time_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,11 @@ func TestTimeJSON(t *testing.T) {
}{
{Time(1), `0.001`},
{Time(-1), `-0.001`},
{Time(1001), `1.001`},
{Time(-1001), `-1.001`},
{Time(123000), `123`},
{Time(123100), `123.1`},
{Time(123010), `123.01`},
}

for i, test := range tests {
Expand Down Expand Up @@ -460,3 +465,17 @@ func BenchmarkParseDuration(b *testing.B) {
require.NoError(b, err)
}
}

func BenchmarkUnmarshalTime(b *testing.B) {
cases := []string{"1780924784", "1780924784.01", "1780924784.001"}

for _, c := range cases {
b.Run(c, func(b *testing.B) {
var t Time
data := []byte(c)
for b.Loop() {
_ = t.UnmarshalJSON(data)
}
})
}
}
Loading