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

svn commit: r911054 - /ofbiz/trunk/framework/base/src/org/ofbiz/base/util/TimeDuration.java

Author: adrianc
Date: Wed Feb 17 16:25:55 2010
New Revision: 911054

URL: http://svn.apache.org/viewvc?rev=911054&view=rev
Log:
Fixed a bug in TimeDuration.java reported by Adam Heath on the dev mailing list. The elapsed time constructor would produce an incorrect duration if either Calendar was prior to the epoch.

Modified:
    ofbiz/trunk/framework/base/src/org/ofbiz/base/util/TimeDuration.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=911054&r1=911053&r2=911054&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 16:25:55 2010
@@ -182,9 +182,13 @@
             calEnd = (Calendar) cal1.clone();
         }
 
-        // this will be used to speed up time comparisons
+        /* Strategy: Using millisecond arithmetic alone will produce inaccurate results.
+         * Using a Calendar alone will take too long. So, we use millisecond arithmetic
+         * to get near the correct result, then zero in on the correct result using a
+         * Calendar.
+         */
         long targetMillis = calEnd.getTimeInMillis();
-        long deltaMillis = targetMillis - calStart.getTimeInMillis();
+        long deltaMillis = computeDeltaMillis(calStart.getTimeInMillis(), targetMillis);
 
         // shortcut for equal dates
         if (deltaMillis == 0) {
@@ -195,33 +199,33 @@
         long yearMillis = 86400000 * calStart.getMinimum(Calendar.DAY_OF_YEAR);
         float units = deltaMillis / yearMillis;
         this.years = advanceCalendar(calStart, calEnd, (int) units, Calendar.YEAR);
-        deltaMillis = targetMillis - calStart.getTimeInMillis();
+        deltaMillis = computeDeltaMillis(calStart.getTimeInMillis(), targetMillis);
 
         // compute elapsed months
         long monthMillis = 86400000 * calStart.getMinimum(Calendar.DAY_OF_MONTH);
         units = deltaMillis / monthMillis;
         this.months = advanceCalendar(calStart, calEnd, (int) units, Calendar.MONTH);
-        deltaMillis = targetMillis - calStart.getTimeInMillis();
+        deltaMillis = computeDeltaMillis(calStart.getTimeInMillis(), targetMillis);
 
         // compute elapsed days
         units = deltaMillis / 86400000;
         this.days = advanceCalendar(calStart, calEnd, (int) units, Calendar.DAY_OF_MONTH);
-        deltaMillis = targetMillis - calStart.getTimeInMillis();
+        deltaMillis = computeDeltaMillis(calStart.getTimeInMillis(), targetMillis);
 
         // compute elapsed hours
         units = deltaMillis / 3600000;
         this.hours = advanceCalendar(calStart, calEnd, (int) units, Calendar.HOUR);
-        deltaMillis = targetMillis - calStart.getTimeInMillis();
+        deltaMillis = computeDeltaMillis(calStart.getTimeInMillis(), targetMillis);
 
         // compute elapsed minutes
         units = deltaMillis / 60000;
         this.minutes = advanceCalendar(calStart, calEnd, (int) units, Calendar.MINUTE);
-        deltaMillis = targetMillis - calStart.getTimeInMillis();
+        deltaMillis = computeDeltaMillis(calStart.getTimeInMillis(), targetMillis);
 
         // compute elapsed seconds
         units = deltaMillis / 1000;
         this.seconds = advanceCalendar(calStart, calEnd, (int) units, Calendar.SECOND);
-        deltaMillis = targetMillis - calStart.getTimeInMillis();
+        deltaMillis = computeDeltaMillis(calStart.getTimeInMillis(), targetMillis);
 
         this.millis = (int) deltaMillis;
         if (isNegative) {
@@ -229,6 +233,13 @@
         }
     }
 
+    protected long computeDeltaMillis(long start, long end) {
+        if (start < 0) {
+            return end + (-start);
+        }
+        return end - start;
+    }
+
     protected int advanceCalendar(Calendar start, Calendar end, int units, int type) {
         if (units >= 1) {
             // Bother, the below needs explanation.