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