}
return d
}
-
- ts, us := t.sec(), u.sec()
-
- var sec, nsec, d int64
-
- ssub := ts - us
- if (ssub < ts) != (us > 0) {
- goto overflow
- }
-
- if ssub < int64(minDuration/Second) || ssub > int64(maxDuration/Second) {
- goto overflow
- }
- sec = ssub * int64(Second)
-
- nsec = int64(t.nsec() - u.nsec())
- d = sec + nsec
- if (d > sec) != (nsec > 0) {
- goto overflow
- }
- return Duration(d)
-
-overflow:
- if t.Before(u) {
+ d := Duration(t.sec()-u.sec())*Second + Duration(t.nsec()-u.nsec())
+ // Check for overflow or underflow.
+ switch {
+ case u.Add(d).Equal(t):
+ return d // d is correct
+ case t.Before(u):
return minDuration // t - u is negative out of range
+ default:
+ return maxDuration // t - u is positive out of range
}
- return maxDuration // t - u is positive out of range
}
// Since returns the time elapsed since t.
Date(0, 1, 2, 3, 4, 5, 6, UTC),
Date(7, 8, 9, 10, 11, 12, 13, FixedZone("", 0)),
Unix(81985467080890095, 0x76543210), // Time.sec: 0x0123456789ABCDEF
- {}, // nil location
+ {}, // nil location
Date(1, 2, 3, 4, 5, 6, 7, FixedZone("", 32767*60)),
Date(1, 2, 3, 4, 5, 6, 7, FixedZone("", -32768*60)),
}
}
}
-func BenchmarkSub(b *testing.B) {
- for i := 0; i < b.N; i++ {
- for _, st := range subTests {
- st.t.Sub(st.u)
- }
- }
-}
-
var nsDurationTests = []struct {
d Duration
want int64