}
return d
}
- 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):
+
+ 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) {
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