summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorJonathan Bernard <jonathan@edgecase.io>2016-10-12 15:32:39 -0500
committerJonathan Bernard <jonathan@edgecase.io>2016-10-12 15:44:21 -0500
commit68d3486f5aacff54345da6ec732974daff53f6f2 (patch)
treeddf46f1675d9aad314ff88aa67b0acfcf3e12bf4
parentb77fb67fee2aca5dabbcfb6aff8cef0607ede9d0 (diff)
downloadNim-68d3486f5aacff54345da6ec732974daff53f6f2.tar.gz
Bugfix for times.initInterval (issue #4889)
`initInterval` had logic to calculate and carry overflowed fields (65 seconds
turns into 5 seconds and carries 1 minute). However, we were not including that
carried value when we recalculate the carry over for the next period of time.So
if you had, for example, 3600 seconds, we carried 60 minutes into the minutes
calculation, but when we calculated how much we should carry into the hours
value we only considered what the user originally supplied for the minutes
field, and forgot to include those 60 carried minute.

So, for example, with the previous implementation this was true:

`seconds(60 * 60 * 24) == seconds(0)`

Or, as failing tests:

```nimrod
import times

assert seconds(60 * 60 * 24) != seconds(0)
assert seconds(60 * 60 * 24) == days(1)
```
-rw-r--r--lib/pure/times.nim16
-rw-r--r--tests/stdlib/ttime.nim9
2 files changed, 16 insertions, 9 deletions
diff --git a/lib/pure/times.nim b/lib/pure/times.nim
index b78a2b966..3e3176ab8 100644
--- a/lib/pure/times.nim
+++ b/lib/pure/times.nim
@@ -266,13 +266,13 @@ proc initInterval*(milliseconds, seconds, minutes, hours, days, months,
   result.milliseconds = `mod`(milliseconds, 1000)
   carryO = `div`(milliseconds, 1000)
   result.seconds = `mod`(carryO + seconds, 60)
-  carryO = `div`(seconds, 60)
+  carryO = `div`(carryO + seconds, 60)
   result.minutes = `mod`(carryO + minutes, 60)
-  carryO = `div`(minutes, 60)
+  carryO = `div`(carryO + minutes, 60)
   result.hours = `mod`(carryO + hours, 24)
-  carryO = `div`(hours, 24)
+  carryO = `div`(carryO + hours, 24)
   result.days = carryO + days
-  carryO = 0
+
   result.months = `mod`(months, 12)
   carryO = `div`(months, 12)
   result.years = carryO + years
@@ -283,13 +283,13 @@ proc `+`*(ti1, ti2: TimeInterval): TimeInterval =
   result.milliseconds = `mod`(ti1.milliseconds + ti2.milliseconds, 1000)
   carryO = `div`(ti1.milliseconds + ti2.milliseconds, 1000)
   result.seconds = `mod`(carryO + ti1.seconds + ti2.seconds, 60)
-  carryO = `div`(ti1.seconds + ti2.seconds, 60)
+  carryO = `div`(carryO + ti1.seconds + ti2.seconds, 60)
   result.minutes = `mod`(carryO + ti1.minutes + ti2.minutes, 60)
-  carryO = `div`(ti1.minutes + ti2.minutes, 60)
+  carryO = `div`(carryO + ti1.minutes + ti2.minutes, 60)
   result.hours = `mod`(carryO + ti1.hours + ti2.hours, 24)
-  carryO = `div`(ti1.hours + ti2.hours, 24)
+  carryO = `div`(carryO + ti1.hours + ti2.hours, 24)
   result.days = carryO + ti1.days + ti2.days
-  carryO = 0
+
   result.months = `mod`(ti1.months + ti2.months, 12)
   carryO = `div`(ti1.months + ti2.months, 12)
   result.years = carryO + ti1.years + ti2.years
diff --git a/tests/stdlib/ttime.nim b/tests/stdlib/ttime.nim
index 3ab287c4e..b3103b412 100644
--- a/tests/stdlib/ttime.nim
+++ b/tests/stdlib/ttime.nim
@@ -140,4 +140,11 @@ doAssert initInterval(months = 13) == initInterval(months = 1, years = 1)
 # Bug with adding a day to a Time
 let day = 24.hours
 let tomorrow = getTime() + day
-doAssert tomorrow - getTime() == 60*60*24
\ No newline at end of file
+doAssert tomorrow - getTime() == 60*60*24
+
+doAssert milliseconds(1000 * 60) == minutes(1)
+doAssert milliseconds(1000 * 60 * 60) == hours(1)
+doAssert milliseconds(1000 * 60 * 60 * 24) == days(1)
+doAssert seconds(60 * 60) == hours(1)
+doAssert seconds(60 * 60 * 24) == days(1)
+doAssert seconds(60 * 60 + 65) == (hours(1) + minutes(1) + seconds(5))