var (
MinMonoTime = Time{wall: 1 << 63, ext: -1 << 63, loc: UTC}
MaxMonoTime = Time{wall: 1 << 63, ext: 1<<63 - 1, loc: UTC}
+
+ NotMonoNegativeTime = Time{wall: 0, ext: -1<<63 + 50}
)
t.stripMono()
}
- // TODO: Check for overflow.
- t.ext += d
+ // Check if the sum of t.ext and d overflows and handle it properly.
+ sum := t.ext + d
+ if (sum > t.ext) == (d > 0) {
+ t.ext = sum
+ } else if d > 0 {
+ t.ext = 1<<63 - 1
+ } else {
+ t.ext = -(1<<63 - 1)
+ }
}
// setLoc sets the location associated with the time.
tzFixed := FixedZone("FIXED_TIME", 12345)
tests := [...]struct {
- time Time
+ time Time
want bool
}{
0: {Date(2009, 1, 1, 12, 0, 0, 0, UTC), false},
}
}
}
+
+func TestTimeAddSecOverflow(t *testing.T) {
+ // Test it with positive delta.
+ var maxInt64 int64 = 1<<63 - 1
+ timeExt := maxInt64 - UnixToInternal - 50
+ notMonoTime := Unix(timeExt, 0)
+ for i := int64(0); i < 100; i++ {
+ sec := notMonoTime.Unix()
+ notMonoTime = notMonoTime.Add(Duration(i * 1e9))
+ if newSec := notMonoTime.Unix(); newSec != sec+i && newSec+UnixToInternal != maxInt64 {
+ t.Fatalf("time ext: %d overflows with positive delta, overflow threshold: %d", newSec, maxInt64)
+ }
+ }
+
+ // Test it with negative delta.
+ maxInt64 = -maxInt64
+ notMonoTime = NotMonoNegativeTime
+ for i := int64(0); i > -100; i-- {
+ sec := notMonoTime.Unix()
+ notMonoTime = notMonoTime.Add(Duration(i * 1e9))
+ if newSec := notMonoTime.Unix(); newSec != sec+i && newSec+UnixToInternal != maxInt64 {
+ t.Fatalf("time ext: %d overflows with positive delta, overflow threshold: %d", newSec, maxInt64)
+ }
+ }
+}