1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 package org.apache.hc.core5.util;
29
30 import java.text.ParseException;
31 import java.util.Locale;
32 import java.util.concurrent.TimeUnit;
33
34 import org.apache.hc.core5.annotation.Contract;
35 import org.apache.hc.core5.annotation.ThreadingBehavior;
36
37
38
39
40
41
42 @Contract(threading = ThreadingBehavior.IMMUTABLE)
43 public class TimeValue implements Comparable<TimeValue> {
44
45 static final int INT_UNDEFINED = -1;
46
47
48
49
50 public static final TimeValue MAX_VALUE = ofDays(Long.MAX_VALUE);
51
52
53
54
55 public static final TimeValue NEG_ONE_MILLISECOND = TimeValue.of(INT_UNDEFINED, TimeUnit.MILLISECONDS);
56
57
58
59
60 public static final TimeValue NEG_ONE_SECOND = TimeValue.of(INT_UNDEFINED, TimeUnit.SECONDS);
61
62
63
64
65 public static final TimeValue ZERO_MILLISECONDS = TimeValue.of(0, TimeUnit.MILLISECONDS);
66
67
68
69
70
71
72
73
74
75
76
77
78 public static int asBoundInt(final long value) {
79 if (value > Integer.MAX_VALUE) {
80 return Integer.MAX_VALUE;
81 } else if (value < Integer.MIN_VALUE) {
82 return Integer.MIN_VALUE;
83 }
84 return (int) value;
85 }
86
87
88
89
90
91
92
93
94
95 public static <T extends TimeValue> T defaultsTo(final T timeValue, final T defaultValue) {
96 return timeValue != null ? timeValue : defaultValue;
97 }
98
99
100
101
102
103
104
105
106 public static TimeValueeValue defaultsToNegativeOneMillisecond(final TimeValue timeValue) {
107 return defaultsTo(timeValue, NEG_ONE_MILLISECOND);
108 }
109
110
111
112
113
114
115
116
117 public static TimeValue">TimeValue defaultsToNegativeOneSecond(final TimeValue timeValue) {
118 return defaultsTo(timeValue, NEG_ONE_SECOND);
119 }
120
121
122
123
124
125
126
127
128 public static TimeValuee">TimeValue defaultsToZeroMilliseconds(final TimeValue timeValue) {
129 return defaultsTo(timeValue, ZERO_MILLISECONDS);
130 }
131
132 public static boolean isNonNegative(final TimeValue timeValue) {
133 return timeValue != null && timeValue.getDuration() >= 0;
134 }
135
136 public static boolean isPositive(final TimeValue timeValue) {
137 return timeValue != null && timeValue.getDuration() > 0;
138 }
139
140
141
142
143
144
145
146
147 public static TimeValue of(final long duration, final TimeUnit timeUnit) {
148 return new TimeValue(duration, timeUnit);
149 }
150
151 public static TimeValue ofDays(final long days) {
152 return of(days, TimeUnit.DAYS);
153 }
154
155 public static TimeValue ofHours(final long hours) {
156 return of(hours, TimeUnit.HOURS);
157 }
158
159 public static TimeValue ofMicroseconds(final long microseconds) {
160 return of(microseconds, TimeUnit.MICROSECONDS);
161 }
162
163 public static TimeValue ofMilliseconds(final long millis) {
164 return of(millis, TimeUnit.MILLISECONDS);
165 }
166
167 public static TimeValue ofMinutes(final long minutes) {
168 return of(minutes, TimeUnit.MINUTES);
169 }
170
171 public static TimeValue ofNanoseconds(final long nanoseconds) {
172 return of(nanoseconds, TimeUnit.NANOSECONDS);
173 }
174
175 public static TimeValue ofSeconds(final long seconds) {
176 return of(seconds, TimeUnit.SECONDS);
177 }
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196 public static TimeValue parse(final String value) throws ParseException {
197 final String split[] = value.trim().split("\\s+");
198 if (split.length < 2) {
199 throw new IllegalArgumentException(
200 String.format("Expected format for <Long><SPACE><java.util.concurrent.TimeUnit>: %s", value));
201 }
202 final String clean0 = split[0].trim();
203 final String clean1 = split[1].trim().toUpperCase(Locale.ROOT);
204 final String timeUnitStr = clean1.endsWith("S") ? clean1 : clean1 + "S";
205 return TimeValue.of(Long.parseLong(clean0), TimeUnit.valueOf(timeUnitStr));
206 }
207
208 private final long duration;
209
210 private final TimeUnit timeUnit;
211
212 TimeValue(final long duration, final TimeUnit timeUnit) {
213 super();
214 this.duration = duration;
215 this.timeUnit = Args.notNull(timeUnit, "timeUnit");
216 }
217
218 public long convert(final TimeUnit targetTimeUnit) {
219 Args.notNull(targetTimeUnit, "timeUnit");
220 return targetTimeUnit.convert(duration, timeUnit);
221 }
222
223 @Override
224 public boolean equals(final Object obj) {
225 if (this == obj) {
226 return true;
227 }
228 if (obj instanceof TimeValue) {
229 final TimeValue./../../../../org/apache/hc/core5/util/TimeValue.html#TimeValue">TimeValue that = (TimeValue) obj;
230 final long thisDuration = this.convert(TimeUnit.NANOSECONDS);
231 final long thatDuration = that.convert(TimeUnit.NANOSECONDS);
232 return thisDuration == thatDuration;
233 }
234 return false;
235 }
236
237
238
239
240
241
242
243
244
245
246 public TimeValue divide(final long divisor) {
247 final long newDuration = duration / divisor;
248 return of(newDuration, timeUnit);
249 }
250
251
252
253
254
255
256
257
258
259
260
261
262 public TimeValue divide(final long divisor, final TimeUnit targetTimeUnit) {
263 return of(convert(targetTimeUnit) / divisor, targetTimeUnit);
264 }
265
266 public long getDuration() {
267 return duration;
268 }
269
270 public TimeUnit getTimeUnit() {
271 return timeUnit;
272 }
273
274 @Override
275 public int hashCode() {
276 int hash = LangUtils.HASH_SEED;
277 hash = LangUtils.hashCode(hash, this.convert(TimeUnit.NANOSECONDS));
278 return hash;
279 }
280
281 public TimeValueTimeValue.html#TimeValue">TimeValue min(final TimeValue other) {
282 return this.compareTo(other) > 0 ? other : this;
283 }
284
285 private TimeUnit min(final TimeUnit other) {
286 return scale() > scale(other) ? other : getTimeUnit();
287 }
288
289 private int scale() {
290 return scale(timeUnit);
291 }
292
293
294
295
296
297
298
299
300 private int scale(final TimeUnit tUnit) {
301 switch (tUnit) {
302 case NANOSECONDS:
303 return 1;
304 case MICROSECONDS:
305 return 2;
306 case MILLISECONDS:
307 return 3;
308 case SECONDS:
309 return 4;
310 case MINUTES:
311 return 5;
312 case HOURS:
313 return 6;
314 case DAYS:
315 return 7;
316 default:
317
318 throw new IllegalStateException();
319 }
320 }
321
322 public void sleep() throws InterruptedException {
323 timeUnit.sleep(duration);
324 }
325
326 public void timedJoin(final Thread thread) throws InterruptedException {
327 timeUnit.timedJoin(thread, duration);
328 }
329
330 public void timedWait(final Object obj) throws InterruptedException {
331 timeUnit.timedWait(obj, duration);
332 }
333
334 public long toDays() {
335 return timeUnit.toDays(duration);
336 }
337
338 public long toHours() {
339 return timeUnit.toHours(duration);
340 }
341
342 public long toMicroseconds() {
343 return timeUnit.toMicros(duration);
344 }
345
346 public long toMilliseconds() {
347 return timeUnit.toMillis(duration);
348 }
349
350 public int toMillisecondsIntBound() {
351 return asBoundInt(toMilliseconds());
352 }
353
354 public long toMinutes() {
355 return timeUnit.toMinutes(duration);
356 }
357
358 public long toNanoseconds() {
359 return timeUnit.toNanos(duration);
360 }
361
362 public long toSeconds() {
363 return timeUnit.toSeconds(duration);
364 }
365
366 public int toSecondsIntBound() {
367 return asBoundInt(toSeconds());
368 }
369
370 @Override
371 public int compareTo(final TimeValue other) {
372 final TimeUnit targetTimeUnit = min(other.getTimeUnit());
373 return Long.compare(convert(targetTimeUnit), other.convert(targetTimeUnit));
374 }
375
376 @Override
377 public String toString() {
378 return String.format("%d %s", duration, timeUnit);
379 }
380
381 public Timeout toTimeout() {
382 return Timeout.of(duration, timeUnit);
383 }
384
385 }