Permalink
Browse files

updated Dur constructor that takes 2 dates to use long precision for …

…tracking the duration difference.

this fixes #94 where dates which have a difference in seconds greater than Integer.MAX_VALUE would incorrectly calculate duration due to Integer overflow.
  • Loading branch information...
Tom Schaible
Tom Schaible committed Jul 9, 2016
1 parent 49e1e80 commit d2154abe8b6dfa868bc52741fdbc254a6e6c8eaf
@@ -222,7 +222,7 @@ public Dur(final Date date1, final Date date2) {
// Init our duration interval (which is in units that evolve as we
// compute, below)
- int dur = 0;
+ long dur = 0;
// Count days to get to the right year (loop in the very rare chance
// that a leap year causes us to come up short)
@@ -251,13 +251,13 @@ public Dur(final Date date1, final Date date2) {
dur += endCal.get(Calendar.SECOND) - startCal.get(Calendar.SECOND);
// Now unwind our units
- seconds = dur % SECONDS_PER_MINUTE;
+ seconds = (int) (dur % SECONDS_PER_MINUTE);
dur = dur / SECONDS_PER_MINUTE; // seconds -> minutes (drop remainder seconds)
- minutes = dur % MINUTES_PER_HOUR;
+ minutes = (int) (dur % MINUTES_PER_HOUR);
dur /= MINUTES_PER_HOUR; // minutes -> hours (drop remainder minutes)
- hours = dur % HOURS_PER_DAY;
+ hours = (int) (dur % HOURS_PER_DAY);
dur /= HOURS_PER_DAY; // hours -> days (drop remainder hours)
- days = dur;
+ days = (int) dur;
weeks = 0;
// Special case for week-only representation
@@ -31,7 +31,9 @@
*/
package net.fortuna.ical4j.model;
+import java.text.DateFormat;
import java.text.ParseException;
+import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
@@ -271,6 +273,18 @@ public static TestSuite suite() throws ParseException {
Dur oneSecond = new Dur("P1S");
Dur twoSeconds = new Dur("P2S");
+
+ //set up a Duration which has seconds that overflow the integer boundary
+ TimeZone tz = TimeZone.getTimeZone("UTC");
+ DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
+ df.setTimeZone(tz);
+
+ Calendar overflow = Calendar.getInstance(tz);
+ overflow.setTime(start);
+ overflow.add(Calendar.SECOND, Integer.MAX_VALUE);
+ overflow.add(Calendar.SECOND, 1);
+ Dur durationOverflow = new Dur(start, overflow.getTime());
+
suite.addTest(new DurTest("testEquals", oneWeek.add(oneWeek), twoWeeks));
suite.addTest(new DurTest("testEquals", oneDay.add(oneDay), twoDays));
suite.addTest(new DurTest("testEquals", oneHour.add(oneHour), twoHours));
@@ -289,6 +303,8 @@ public static TestSuite suite() throws ParseException {
suite.addTest(new DurTest("testEquals", new Dur(0, 0, -59, 0).add(twoMinutes.negate()), new Dur("-P1H1M")));
suite.addTest(new DurTest("testEquals", new Dur(0, 0, 0, -59).add(twoSeconds.negate()), new Dur("-P1M1S")));
+ suite.addTest(new DurTest("testEquals", durationOverflow, new Dur("P24855DT3H14M8S")));
+
suite.addTest(new DurTest("testCompareToGreater", new Dur(1), new Dur(-1)));
suite.addTest(new DurTest("testCompareToGreater", new Dur(0, 0, 0, 3), new Dur(0, 0, 0, -5)));
suite.addTest(new DurTest("testCompareToGreater", new Dur(0, 0, 0, 5), new Dur(0, 0, 0, 3)));

0 comments on commit d2154ab

Please sign in to comment.