Skip to content

time: add Duration.Abs #51414

Closed
Closed
@earthboundkid

Description

@earthboundkid

#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.

See playground:

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.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions