Closed
Description
#50770 adds Time.Compare, which is good, however, as noted in the issue, because times have nanosecond precision, it is unusual for times to be exactly equal to each other unless they've been truncated somehow. One might think, oh, no big deal, just do | t1 - t2 | < delta. It isn't such a big deal, but there is a subtle bug here (which bit me, naturally). time.Durations are measured as nanoseconds and can only measure 260 years or so. If t1 is the zero time and t2 is not, t1.Sub(t2) produces a Duration that cannot be converted from negative to positive because it is math.MinInt64.
func withinBad(t1, t2 time.Time, delta time.Duration) bool {
diff := t1.Sub(t2)
if diff < 0 {
diff *= -1
}
return diff < delta
}
func withinGood(t1, t2 time.Time, delta time.Duration) bool {
if t2.Before(t1) {
t1, t2 = t2, t1
}
diff := t2.Sub(t1)
return diff < delta
}
func main() {
t1 := time.Time{}
t2 := time.Now()
fmt.Println(withinBad(t1, t2, 1*time.Second)) // true !!
fmt.Println(withinBad(t2, t1, 1*time.Second)) // false
fmt.Println(withinGood(t1, t2, 1*time.Second)) // false
fmt.Println(withinGood(t2, t1, 1*time.Second)) // false
}
Anyhow, getting this right seems subtle enough to be worth adding a helper method to time.Time.