Clover coverage report - JBind Project
Coverage timestamp: Fr Mai 28 2004 11:17:36 CEST
file stats: LOC: 254   Methods: 14
NCLOC: 183   Classes: 1
This license of Clover is provided to support the development of JBind only. Please visit http://www.thecortex.net/clover to obtain a licensed version of Clover.
 
 Source file Conditionals Statements Methods TOTAL
TimeHelper.java 61,5% 78,3% 78,6% 73,7%
 1   
 /*
 2   
  * JBind
 3   
  *
 4   
  * Copyright (c) by Stefan Wachter. All rights reserved.
 5   
  *
 6   
  * Usage, modification, and redistribution is subject to license terms that are
 7   
  * available at 'http://www.jbind.org'. The JBind license is like the
 8   
  * 'Apache Software License V 1.1'.
 9   
  */
 10   
 package org.jbind.xml.instance.data;
 11   
 
 12   
 import java.math.BigDecimal;
 13   
 
 14   
 import org.jbind.util.other.StrBuffer;
 15   
 import org.jbind.xml.core.data.IDateTime;
 16   
 import org.jbind.xml.core.data.IDurationBase;
 17   
 import org.jbind.xml.core.data.ITime;
 18   
 import org.jbind.xml.core.data.ITimeZone;
 19   
 
 20   
 public class TimeHelper {
 21   
 
 22  0
   private TimeHelper() {}
 23   
 
 24  4
   public static ITime add(ITime aTime, ITimeZone aDuration) {
 25  4
     int tmp, carry;
 26  4
     int s = -aDuration.getSign();
 27   
 
 28  4
     BigDecimal fraction = null;
 29  4
     if ((null != aTime.getFraction()) && (null != aDuration.getFraction())) {
 30  0
       fraction = (s == 1) ? aTime.getFraction().add(aDuration.getFraction()) : aTime.getFraction().subtract(aDuration.getFraction());
 31  4
     } else if (null != aTime.getFraction()) {
 32  4
       fraction = aTime.getFraction();
 33  0
     } else if (null != aDuration.getFraction()) {
 34  0
       fraction = (s == 1) ? aDuration.getFraction().negate() : aDuration.getFraction();
 35   
     }
 36  4
     BigDecimal one = new BigDecimal("1");
 37  4
     if (fraction.compareTo(one) > 0) {
 38  0
       fraction = fraction.subtract(one);
 39  0
       carry = 1;
 40  4
     } else if (fraction.signum() < 0) {
 41  0
       fraction = fraction.add(one);
 42  0
       carry = -1;
 43   
     } else {
 44  4
       carry = 0;
 45   
     }
 46   
 
 47  4
     tmp = aTime.getSecond() + s * aDuration.getSeconds() + carry;
 48  4
     carry = fQuotient(tmp, 60);
 49  4
     int second = mod(tmp, 60, carry);
 50   
 
 51  4
     tmp = aTime.getMinute() + s * aDuration.getMinutes() + carry;
 52  4
     carry = fQuotient(tmp, 60);
 53  4
     int minute = mod(tmp, 60, carry);
 54   
 
 55  4
     tmp = aTime.getHour() + s * aDuration.getHours() + carry;
 56  4
     carry = fQuotient(tmp, 24);
 57  4
     int hour = mod(tmp, 24, carry);
 58   
 
 59  4
     return new Time(hour, minute, second, fraction, aTime.hadTimeZone());
 60   
   }
 61   
 
 62  0
   public static IDateTime add(IDateTime aDateTime, IDurationBase aDuration) {
 63  0
     return addOrSubtract(aDateTime, aDuration, true);
 64   
   }
 65   
 
 66  9
   public static IDateTime subtract(IDateTime aDateTime, IDurationBase aDuration) {
 67  9
     return addOrSubtract(aDateTime, aDuration, false);
 68   
   }
 69   
 
 70  9
   private static IDateTime addOrSubtract(IDateTime aDateTime, IDurationBase aDuration, boolean anAddNotSubtract) {
 71  9
     int s = aDateTime.getSign() * aDuration.getSign();
 72  9
     if (!anAddNotSubtract) {
 73  9
       s *= -1;
 74   
     }
 75  9
     int tmp, carry;
 76   
 
 77  9
     tmp = aDateTime.getMonth() + s * aDuration.getMonths();
 78  9
     carry = fQuotient(tmp, 1, 13);
 79  9
     int month = modulo(tmp, 1, 13);
 80   
 
 81  9
     int year = aDateTime.getYear() + s * aDuration.getYears() + carry;
 82  9
     if (year == 0) {
 83  0
       year += s;
 84   
     }
 85   
 
 86  9
     BigDecimal fraction = null;
 87  9
     if ((null != aDateTime.getFraction()) && (null != aDuration.getFraction())) {
 88  0
       fraction = (s == 1) ? aDateTime.getFraction().add(aDuration.getFraction()) : aDateTime.getFraction().subtract(aDuration.getFraction());
 89  9
     } else if (null != aDateTime.getFraction()) {
 90  0
       fraction = aDateTime.getFraction();
 91  9
     } else if (null != aDuration.getFraction()) {
 92  0
       fraction = (s == 1) ? aDuration.getFraction().negate() : aDuration.getFraction();
 93   
     }
 94  9
     if (null != fraction) {
 95  0
       BigDecimal one = new BigDecimal("1");
 96  0
       if (fraction.compareTo(one) > 0) {
 97  0
         fraction = fraction.subtract(one);
 98  0
         carry = 1;
 99  0
       } else if (fraction.signum() < 0) {
 100  0
         fraction = fraction.add(one);
 101  0
         carry = -1;
 102   
       } else {
 103  0
         carry = 0;
 104   
       }
 105   
     }
 106   
 
 107  9
     tmp = aDateTime.getSecond() + s * aDuration.getSeconds() + carry;
 108  9
     carry = fQuotient(tmp, 60);
 109  9
     int second = mod(tmp, 60, carry);
 110   
 
 111  9
     tmp = aDateTime.getMinute() + s * aDuration.getMinutes() + carry;
 112  9
     carry = fQuotient(tmp, 60);
 113  9
     int minute = mod(tmp, 60, carry);
 114   
 
 115  9
     tmp = aDateTime.getHour() + s * aDuration.getHours() + carry;
 116  9
     carry = fQuotient(tmp, 24);
 117  9
     int hour = mod(tmp, 24, carry);
 118   
 
 119  9
     int tmpDay;
 120  9
     if (aDateTime.getDay() > maxDayInMonthFor(year, month)) {
 121  0
       tmpDay = maxDayInMonthFor(year, month);
 122   
     } else {
 123  9
       tmpDay = aDateTime.getDay();
 124   
     }
 125   
 
 126  9
     int day = tmpDay + s * aDuration.getDays() + carry;
 127   
 
 128  9
     while (true) {
 129  11
       if (day < 1) {
 130  1
         day = day + maxDayInMonthFor(year, month - 1);
 131  1
         carry = -1;
 132  10
       } else if (day > maxDayInMonthFor(year, month)) {
 133  1
         day = day - maxDayInMonthFor(year, month);
 134  1
         carry = 1;
 135   
       } else {
 136  9
         break;
 137   
       }
 138  2
       tmp = month + carry;
 139  2
       month = modulo(tmp, 1, 13);
 140  2
       year = year + fQuotient(tmp, 1, 13);
 141  2
       if (year == 0) {
 142  0
         year += s;
 143   
       }
 144   
     }
 145   
 
 146  9
     int sign;
 147  9
     if (year > 0) {
 148  9
       sign = aDateTime.getSign();
 149   
     } else {
 150  0
       sign = -aDateTime.getSign();
 151  0
       year = -year;
 152   
     }
 153   
 
 154  9
     return new DateTime(sign, year, month, day, hour, minute, second, fraction, aDateTime.hadTimeZone());
 155   
   }
 156   
 
 157   
   /**
 158   
    * Given {year,month} computes maximum
 159   
    * number of days for given month
 160   
    *
 161   
    * @param year
 162   
    * @param month
 163   
    * @return integer containg the number of days in a given month
 164   
    */
 165  46
   public static int maxDayInMonthFor(int aYear, int aMonth) {
 166  46
     int month = modulo(aMonth, 1, 13);
 167  46
     int year = aYear + fQuotient(aMonth, 1, 13);
 168   
 
 169   
     //validate days
 170  46
     if ((month == 4) || (month == 6) || (month == 9) || (month == 11)) {
 171  6
       return 30;
 172  40
     } else if (month == 2) {
 173  9
       if (isLeapYear(year)) {
 174  6
         return 29;
 175   
       } else {
 176  3
         return 28;
 177   
       }
 178   
     } else {
 179  31
       return 31;
 180   
     }
 181   
   }
 182   
 
 183  9
   private static boolean isLeapYear(int year) {
 184  9
     if (year == 0) {
 185  0
       return false;
 186   
     }
 187   
     //REVISIT: should we take care about Julian calendar?
 188  9
     return ((year % 4 == 0) && ((year % 100 != 0) || (year % 400 == 0)));
 189   
   }
 190   
 
 191  0
   private static int modulo(int a, int b) {
 192  0
     return a - fQuotient(a, b) * b;
 193   
   }
 194   
 
 195   
   //
 196   
   // help function described in W3C PR Schema [E Adding durations to dateTimes]
 197   
   //
 198  96
   private static int mod(int a, int b, int quotient) {
 199   
     //modulo(a, b) = a - fQuotient(a,b)*b
 200  96
     return (a - quotient * b);
 201   
   }
 202   
 
 203   
   //
 204   
   // help function described in W3C PR Schema [E Adding durations to dateTimes]
 205   
   //
 206  153
   private static int fQuotient(int a, int b) {
 207   
     //fQuotient(a, b) = the greatest integer less than or equal to a/b
 208  153
     return (int)Math.floor((float)a / b);
 209   
   }
 210   
 
 211   
   //
 212   
   // help function described in W3C PR Schema [E Adding durations to dateTimes]
 213   
   //
 214  57
   private static int modulo(int temp, int low, int high) {
 215   
     //modulo(a - low, high - low) + low
 216  57
     int a = temp - low;
 217  57
     int b = high - low;
 218  57
     return (mod(a, b, fQuotient(a, b)) + low);
 219   
   }
 220   
 
 221   
   //
 222   
   // help function described in W3C PR Schema [E Adding durations to dateTimes]
 223   
   //
 224  57
   private static int fQuotient(int temp, int low, int high) {
 225   
     //fQuotient(a - low, high - low)
 226   
 
 227  57
     return fQuotient(temp - low, high - low);
 228   
   }
 229   
 
 230  3
   public static void output(int anInt, int aLength, StrBuffer aStringBuffer) {
 231  3
     StrBuffer b = new StrBuffer();
 232  3
     int x = anInt;
 233  3
     for (int i = 0; i < aLength; i++, x /= 10) {
 234  6
       b.append((char)('0' + x % 10));
 235   
     }
 236   
     assert 0 == x;
 237  3
     for (int i = b.length(); --i >= 0; ) {
 238  6
       aStringBuffer.append(b.charAt(i));
 239   
     }
 240   
   }
 241   
 
 242  6
   public static void output(int anInt, StrBuffer aStrBuffer) {
 243  6
     int x = anInt;
 244  6
     StrBuffer b = new StrBuffer();
 245  6
     do {
 246  9
       b.append((char)('0' + x % 10));
 247  9
       x /= 10;
 248  9
     } while (x != 0);
 249  6
     for (int i = b.length(); --i >= 0; ) {
 250  9
       aStrBuffer.append(b.charAt(i));
 251   
     }
 252   
   }
 253   
 }
 254