You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ofbiz.apache.org by do...@apache.org on 2010/02/17 06:18:27 UTC

svn commit: r910830 - in /ofbiz/trunk/framework/base/src/org/ofbiz/base/util: TimeDuration.java test/TimeDurationTests.java

Author: doogie
Date: Wed Feb 17 05:18:27 2010
New Revision: 910830

URL: http://svn.apache.org/viewvc?rev=910830&view=rev
Log:
A rather complex fix for dealing with calendar dates that have a DAY
value that is in the special window of 29-31.

Modified:
    ofbiz/trunk/framework/base/src/org/ofbiz/base/util/TimeDuration.java
    ofbiz/trunk/framework/base/src/org/ofbiz/base/util/test/TimeDurationTests.java

Modified: ofbiz/trunk/framework/base/src/org/ofbiz/base/util/TimeDuration.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/base/src/org/ofbiz/base/util/TimeDuration.java?rev=910830&r1=910829&r2=910830&view=diff
==============================================================================
--- ofbiz/trunk/framework/base/src/org/ofbiz/base/util/TimeDuration.java (original)
+++ ofbiz/trunk/framework/base/src/org/ofbiz/base/util/TimeDuration.java Wed Feb 17 05:18:27 2010
@@ -231,11 +231,33 @@
 
     protected int advanceCalendar(Calendar start, Calendar end, int units, int type) {
         if (units >= 1) {
-            start.add(type, units);
-            while (start.after(end)) {
-                start.add(type, -1);
+            // Bother, the below needs explanation.
+            //
+            // If start has a day value of 31, and you add to the month,
+            // and the target month is not allowed to have 31 as the day
+            // value, then the day will be changed to a value that is in
+            // range.  But, when the code needs to then subtract 1 from
+            // the month, because it has advanced to far, the day is *not*
+            // set back to the original value of 31.
+            //
+            // This bug can be triggered by having a duration of -1 day,
+            // then adding this duration to a calendar that represents 0
+            // milliseconds, then creating a new duration by using the 2
+            // Calendar constructor, with cal1 being 0, and cal2 being the
+            // new calendar that you added the duration to.
+            //
+            // To solve this problem, we make a temporary copy of the
+            // start calendar, and only modify it if we actually have to.
+            Calendar tmp = (Calendar) start.clone();
+            int tmpUnits = units;
+            tmp.add(type, tmpUnits);
+            while (tmp.after(end)) {
+                tmp.add(type, -1);
                 units--;
             }
+            if (units != 0) {
+                start.add(type, units);
+            }
         }
         return units;
     }

Modified: ofbiz/trunk/framework/base/src/org/ofbiz/base/util/test/TimeDurationTests.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/base/src/org/ofbiz/base/util/test/TimeDurationTests.java?rev=910830&r1=910829&r2=910830&view=diff
==============================================================================
--- ofbiz/trunk/framework/base/src/org/ofbiz/base/util/test/TimeDurationTests.java (original)
+++ ofbiz/trunk/framework/base/src/org/ofbiz/base/util/test/TimeDurationTests.java Wed Feb 17 05:18:27 2010
@@ -107,11 +107,9 @@
         assertDurationFields(label + "(parseString[0])", years, months, days, hours, minutes, seconds, milliseconds, durationString, TimeDuration.parseDuration(durationString), isNegative, false);
         assertDurationFields(label + "(parseString)", years, months, days, hours, minutes, seconds, milliseconds, durationString, stringDuration, isNegative, false);
         assertDurationFields(label + "(cal)", years, months, days, hours, minutes, seconds, milliseconds, durationString, calDuration, isNegative, false);
-        if (!isNegative) {
-            Calendar added = calDuration.addToCalendar((Calendar) zero.clone());
-            TimeDuration addDuration = new TimeDuration(zero, added);
-            assertDurationFields(label + "(cal[add])", years, months, days, hours, minutes, seconds, milliseconds, durationString, addDuration, isNegative, false);
-        }
+        Calendar added = calDuration.addToCalendar((Calendar) zero.clone());
+        TimeDuration addDuration = new TimeDuration(zero, added);
+        assertDurationFields(label + "(cal[add])", years, months, days, hours, minutes, seconds, milliseconds, durationString, addDuration, isNegative, false);
         assertEquals(label + ".compareTo(string, cal)", 0, doCompare(stringDuration, calDuration));
         assertEquals(label + ".compareTo(string, string)", 0, doCompare(stringDuration, stringDuration));
         assertEquals(label + ".compareTo(cal, cal)", 0, doCompare(calDuration, calDuration));