1 16 package org.joda.time.field; 17 18 import org.joda.time.DateTimeField; 19 import org.joda.time.DateTimeFieldType; 20 import org.joda.time.DurationField; 21 22 35 public class DividedDateTimeField extends DecoratedDateTimeField { 36 37 private static final long serialVersionUID = 8318475124230605365L; 38 39 final int iDivisor; 41 final DurationField iDurationField; 42 43 private final int iMin; 44 private final int iMax; 45 46 54 public DividedDateTimeField(DateTimeField field, 55 DateTimeFieldType type, int divisor) { 56 super(field, type); 57 58 if (divisor < 2) { 59 throw new IllegalArgumentException ("The divisor must be at least 2"); 60 } 61 62 DurationField unitField = field.getDurationField(); 63 if (unitField == null) { 64 iDurationField = null; 65 } else { 66 iDurationField = new ScaledDurationField( 67 unitField, type.getDurationType(), divisor); 68 } 69 70 iDivisor = divisor; 71 72 int i = field.getMinimumValue(); 73 int min = (i >= 0) ? i / divisor : ((i + 1) / divisor - 1); 74 75 int j = field.getMaximumValue(); 76 int max = (j >= 0) ? j / divisor : ((j + 1) / divisor - 1); 77 78 iMin = min; 79 iMax = max; 80 } 81 82 89 public DividedDateTimeField(RemainderDateTimeField remainderField, DateTimeFieldType type) { 90 super(remainderField.getWrappedField(), type); 91 int divisor = iDivisor = remainderField.iDivisor; 92 iDurationField = remainderField.iRangeField; 93 94 DateTimeField field = getWrappedField(); 95 int i = field.getMinimumValue(); 96 int min = (i >= 0) ? i / divisor : ((i + 1) / divisor - 1); 97 98 int j = field.getMaximumValue(); 99 int max = (j >= 0) ? j / divisor : ((j + 1) / divisor - 1); 100 101 iMin = min; 102 iMax = max; 103 } 104 105 111 public int get(long instant) { 112 int value = getWrappedField().get(instant); 113 if (value >= 0) { 114 return value / iDivisor; 115 } else { 116 return ((value + 1) / iDivisor) - 1; 117 } 118 } 119 120 128 public long add(long instant, int amount) { 129 return getWrappedField().add(instant, amount * iDivisor); 130 } 131 132 140 public long add(long instant, long amount) { 141 return getWrappedField().add(instant, amount * iDivisor); 142 } 143 144 152 public long addWrapField(long instant, int amount) { 153 return set(instant, FieldUtils.getWrappedValue(get(instant), amount, iMin, iMax)); 154 } 155 156 public int getDifference(long minuendInstant, long subtrahendInstant) { 157 return getWrappedField().getDifference(minuendInstant, subtrahendInstant) / iDivisor; 158 } 159 160 public long getDifferenceAsLong(long minuendInstant, long subtrahendInstant) { 161 return getWrappedField().getDifferenceAsLong(minuendInstant, subtrahendInstant) / iDivisor; 162 } 163 164 172 public long set(long instant, int value) { 173 FieldUtils.verifyValueBounds(this, value, iMin, iMax); 174 int remainder = getRemainder(getWrappedField().get(instant)); 175 return getWrappedField().set(instant, value * iDivisor + remainder); 176 } 177 178 181 public DurationField getDurationField() { 182 return iDurationField; 183 } 184 185 190 public int getMinimumValue() { 191 return iMin; 192 } 193 194 199 public int getMaximumValue() { 200 return iMax; 201 } 202 203 public long roundFloor(long instant) { 204 DateTimeField field = getWrappedField(); 205 return field.roundFloor(field.set(instant, get(instant) * iDivisor)); 206 } 207 208 public long remainder(long instant) { 209 return set(instant, get(getWrappedField().remainder(instant))); 210 } 211 212 217 public int getDivisor() { 218 return iDivisor; 219 } 220 221 private int getRemainder(int value) { 222 if (value >= 0) { 223 return value % iDivisor; 224 } else { 225 return (iDivisor - 1) + ((value + 1) % iDivisor); 226 } 227 } 228 229 } 230 | Popular Tags |