|
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. |
| Free forum by Nabble | Edit this page |
