1/* GENERATED SOURCE. DO NOT MODIFY. */ 2/* 3****************************************************************************** 4* Copyright (C) 2007, International Business Machines Corporation and * 5* others. All Rights Reserved. * 6****************************************************************************** 7*/ 8 9package android.icu.impl.duration; 10 11import android.icu.impl.duration.impl.DataRecord.ETimeLimit; 12 13/** 14 * Represents an approximate duration in multiple TimeUnits. Each unit, 15 * if set, has a count (which can be fractional and must be non-negative). 16 * In addition Period can either represent the duration as being into the past 17 * or future, and as being more or less than the defined value. 18 * <p> 19 * Use a PeriodFormatter to convert a Period to a String. 20 * <p> 21 * Periods are immutable. Mutating operations return the new 22 * result leaving the original unchanged. 23 * <p> 24 * Example:<pre> 25 * Period p1 = Period.at(3, WEEK).and(2, DAY).inFuture(); 26 * Period p2 = p1.and(12, HOUR);</pre> 27 * @hide Only a subset of ICU is exposed in Android 28 */ 29public final class Period { 30 final byte timeLimit; 31 final boolean inFuture; 32 final int[] counts; 33 34 /** 35 * Constructs a Period representing a duration of 36 * count units extending into the past. 37 * @param count the number of units, must be non-negative 38 * @param unit the unit 39 * @return the new Period 40 */ 41 public static Period at(float count, TimeUnit unit) { 42 checkCount(count); 43 return new Period(ETimeLimit.NOLIMIT, false, count, unit); 44 } 45 46 /** 47 * Constructs a Period representing a duration more than 48 * count units extending into the past. 49 * @param count the number of units. must be non-negative 50 * @param unit the unit 51 * @return the new Period 52 */ 53 public static Period moreThan(float count, TimeUnit unit) { 54 checkCount(count); 55 return new Period(ETimeLimit.MT, false, count, unit); 56 } 57 58 /** 59 * Constructs a Period representing a duration 60 * less than count units extending into the past. 61 * @param count the number of units. must be non-negative 62 * @param unit the unit 63 * @return the new Period 64 */ 65 public static Period lessThan(float count, TimeUnit unit) { 66 checkCount(count); 67 return new Period(ETimeLimit.LT, false, count, unit); 68 } 69 70 /** 71 * Set the given unit to have the given count. Marks the 72 * unit as having been set. This can be used to set 73 * multiple units, or to reset a unit to have a new count. 74 * This does <b>not</b> add the count to an existing count 75 * for this unit. 76 * 77 * @param count the number of units. must be non-negative 78 * @param unit the unit 79 * @return the new Period 80 */ 81 public Period and(float count, TimeUnit unit) { 82 checkCount(count); 83 return setTimeUnitValue(unit, count); 84 } 85 86 /** 87 * Mark the given unit as not being set. 88 * 89 * @param unit the unit to unset 90 * @return the new Period 91 */ 92 public Period omit(TimeUnit unit) { 93 return setTimeUnitInternalValue(unit, 0); 94 } 95 96 /** 97 * Mark the duration as being at the defined duration. 98 * 99 * @return the new Period 100 */ 101 public Period at() { 102 return setTimeLimit(ETimeLimit.NOLIMIT); 103 } 104 105 /** 106 * Mark the duration as being more than the defined duration. 107 * 108 * @return the new Period 109 */ 110 public Period moreThan() { 111 return setTimeLimit(ETimeLimit.MT); 112 } 113 114 /** 115 * Mark the duration as being less than the defined duration. 116 * 117 * @return the new Period 118 */ 119 public Period lessThan() { 120 return setTimeLimit(ETimeLimit.LT); 121 } 122 123 /** 124 * Mark the time as being in the future. 125 * 126 * @return the new Period 127 */ 128 public Period inFuture() { 129 return setFuture(true); 130 } 131 132 /** 133 * Mark the duration as extending into the past. 134 * 135 * @return the new Period 136 */ 137 public Period inPast() { 138 return setFuture(false); 139 } 140 141 /** 142 * Mark the duration as extending into the future if 143 * future is true, and into the past otherwise. 144 * 145 * @param future true if the time is in the future 146 * @return the new Period 147 */ 148 public Period inFuture(boolean future) { 149 return setFuture(future); 150 } 151 152 /** 153 * Mark the duration as extending into the past if 154 * past is true, and into the future otherwise. 155 * 156 * @param past true if the time is in the past 157 * @return the new Period 158 */ 159 public Period inPast(boolean past) { 160 return setFuture(!past); 161 } 162 163 /** 164 * Returns true if any unit is set. 165 * @return true if any unit is set 166 */ 167 public boolean isSet() { 168 for (int i = 0; i < counts.length; ++i) { 169 if (counts[i] != 0) { 170 return true; 171 } 172 } 173 return false; 174 } 175 176 /** 177 * Returns true if the given unit is set. 178 * @param unit the unit to test 179 * @return true if the given unit is set. 180 */ 181 public boolean isSet(TimeUnit unit) { 182 return counts[unit.ordinal] > 0; 183 } 184 185 /** 186 * Returns the count for the specified unit. If the 187 * unit is not set, returns 0. 188 * @param unit the unit to test 189 * @return the count 190 */ 191 public float getCount(TimeUnit unit) { 192 int ord = unit.ordinal; 193 if (counts[ord] == 0) { 194 return 0; 195 } 196 return (counts[ord] - 1)/1000f; 197 } 198 199 /** 200 * Returns true if this represents a 201 * duration into the future. 202 * @return true if this represents a 203 * duration into the future. 204 */ 205 public boolean isInFuture() { 206 return inFuture; 207 } 208 209 /** 210 * Returns true if this represents a 211 * duration into the past 212 * @return true if this represents a 213 * duration into the past 214 */ 215 public boolean isInPast () { 216 return !inFuture; 217 } 218 219 /** 220 * Returns true if this represents a duration in 221 * excess of the defined duration. 222 * @return true if this represents a duration in 223 * excess of the defined duration. 224 */ 225 public boolean isMoreThan() { 226 return timeLimit == ETimeLimit.MT; 227 } 228 229 /** 230 * Returns true if this represents a duration 231 * less than the defined duration. 232 * @return true if this represents a duration 233 * less than the defined duration. 234 */ 235 public boolean isLessThan() { 236 return timeLimit == ETimeLimit.LT; 237 } 238 239 /** 240 * Returns true if rhs extends Period and 241 * the two Periods are equal. 242 * @param rhs the object to compare to 243 * @return true if rhs is a Period and is equal to this 244 */ 245 public boolean equals(Object rhs) { 246 try { 247 return equals((Period)rhs); 248 } 249 catch (ClassCastException e) { 250 return false; 251 } 252 } 253 254 /** 255 * Returns true if the same units are defined with 256 * the same counts, both extend into the future or both into the 257 * past, and if the limits (at, more than, less than) are the same. 258 * Note that this means that a period of 1000ms and a period of 1sec 259 * will not compare equal. 260 * 261 * @param rhs the period to compare to 262 * @return true if the two periods are equal 263 */ 264 public boolean equals(Period rhs) { 265 if (rhs != null && 266 this.timeLimit == rhs.timeLimit && 267 this.inFuture == rhs.inFuture) { 268 for (int i = 0; i < counts.length; ++i) { 269 if (counts[i] != rhs.counts[i]) { 270 return false; 271 } 272 } 273 return true; 274 } 275 return false; 276 } 277 278 /** 279 * Returns the hashCode. 280 * @return the hashCode 281 */ 282 public int hashCode() { 283 int hc = (timeLimit << 1) | (inFuture ? 1 : 0); 284 for (int i = 0; i < counts.length; ++i) { 285 hc = (hc << 2) ^ counts[i]; 286 } 287 return hc; 288 } 289 290 /** 291 * Private constructor used by static factory methods. 292 */ 293 private Period(int limit, boolean future, float count, TimeUnit unit) { 294 this.timeLimit = (byte) limit; 295 this.inFuture = future; 296 this.counts = new int[TimeUnit.units.length]; 297 this.counts[unit.ordinal] = (int)(count * 1000) + 1; 298 } 299 300 /** 301 * Package private constructor used by setters and factory. 302 */ 303 Period(int timeLimit, boolean inFuture, int[] counts) { 304 this.timeLimit = (byte) timeLimit; 305 this.inFuture = inFuture; 306 this.counts = counts; 307 } 308 309 /** 310 * Set the unit's internal value, converting from float to int. 311 */ 312 private Period setTimeUnitValue(TimeUnit unit, float value) { 313 if (value < 0) { 314 throw new IllegalArgumentException("value: " + value); 315 } 316 return setTimeUnitInternalValue(unit, (int)(value * 1000) + 1); 317 } 318 319 /** 320 * Sets the period to have the provided value, 1/1000 of the 321 * unit plus 1. Thus unset values are '0', 1' is the set value '0', 322 * 2 is the set value '1/1000', 3 is the set value '2/1000' etc. 323 * @param p the period to change 324 * @param value the int value as described above. 325 * @eturn the new Period object. 326 */ 327 private Period setTimeUnitInternalValue(TimeUnit unit, int value) { 328 int ord = unit.ordinal; 329 if (counts[ord] != value) { 330 int[] newCounts = new int[counts.length]; 331 for (int i = 0; i < counts.length; ++i) { 332 newCounts[i] = counts[i]; 333 } 334 newCounts[ord] = value; 335 return new Period(timeLimit, inFuture, newCounts); 336 } 337 return this; 338 } 339 340 /** 341 * Sets whether this defines a future time. 342 * @param future true if the time is in the future 343 * @return the new Period 344 */ 345 private Period setFuture(boolean future) { 346 if (this.inFuture != future) { 347 return new Period(timeLimit, future, counts); 348 } 349 return this; 350 } 351 352 /** 353 * Sets whether this is more than, less than, or 354 * 'about' the specified time. 355 * @param limit the kind of limit 356 * @return the new Period 357 */ 358 private Period setTimeLimit(byte limit) { 359 if (this.timeLimit != limit) { 360 return new Period(limit, inFuture, counts); 361 362 } 363 return this; 364 } 365 366 /** 367 * Validate count. 368 */ 369 private static void checkCount(float count) { 370 if (count < 0) { 371 throw new IllegalArgumentException("count (" + count + 372 ") cannot be negative"); 373 } 374 } 375} 376