1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.common.util;
17
18 import static java.util.concurrent.TimeUnit.MILLISECONDS;
19
20 import java.text.NumberFormat;
21 import java.text.ParseException;
22 import java.text.SimpleDateFormat;
23 import java.util.ArrayList;
24 import java.util.Arrays;
25 import java.util.Date;
26 import java.util.List;
27 import java.util.Map;
28 import java.util.TimeZone;
29
30 import org.apache.commons.lang3.StringUtils;
31 import org.kuali.common.util.base.Exceptions;
32
33 import com.google.common.base.Stopwatch;
34 import com.google.common.collect.Iterables;
35
36
37
38
39
40
41
42 public class FormatUtils {
43
44 public static final double SECOND = 1000;
45 public static final double MINUTE = 60 * SECOND;
46 public static final double HOUR = 60 * MINUTE;
47 public static final double DAY = 24 * HOUR;
48 public static final double YEAR = 365 * DAY;
49
50
51
52
53 public static final String JAVA_UTIL_DATE_TO_STRING_FORMAT = "EEE MMM d HH:mm:ss zzz y";
54 private static final SimpleDateFormat JAVA_UTIL_DATE_TO_STRING_FORMATTER = new SimpleDateFormat(JAVA_UTIL_DATE_TO_STRING_FORMAT);
55
56 private static final String DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ";
57 private static final SimpleDateFormat DATE_FORMATTER = new SimpleDateFormat(DATE_FORMAT);
58
59 private static final List<String> TIME_TOKENS = Arrays.asList("ms", "s", "m", "h", "d", "y");
60 private static final List<Long> TIME_MULTIPLIERS = getTimeMultipliers();
61
62 private static final List<String> SIZE_TOKENS = Arrays.asList("b", "k", "m", "g", "t", "p", "e");
63 private static final int BASE = 1024;
64
65 private static NumberFormat largeSizeFormatter = NumberFormat.getInstance();
66 private static NumberFormat sizeFormatter = NumberFormat.getInstance();
67 private static NumberFormat timeFormatter = NumberFormat.getInstance();
68 private static NumberFormat rateFormatter = NumberFormat.getInstance();
69 private static NumberFormat countFormatter = NumberFormat.getInstance();
70 private static NumberFormat currencyFormatter = NumberFormat.getCurrencyInstance();
71 private static NumberFormat integerFormatter = NumberFormat.getInstance();
72
73 static {
74 integerFormatter.setGroupingUsed(false);
75 integerFormatter.setMaximumFractionDigits(0);
76 integerFormatter.setMinimumFractionDigits(0);
77 sizeFormatter.setGroupingUsed(false);
78 sizeFormatter.setMaximumFractionDigits(1);
79 sizeFormatter.setMinimumFractionDigits(1);
80 largeSizeFormatter.setGroupingUsed(false);
81 largeSizeFormatter.setMaximumFractionDigits(3);
82 largeSizeFormatter.setMinimumFractionDigits(3);
83 timeFormatter.setGroupingUsed(false);
84 timeFormatter.setMaximumFractionDigits(3);
85 timeFormatter.setMinimumFractionDigits(3);
86 rateFormatter.setGroupingUsed(false);
87 rateFormatter.setMaximumFractionDigits(3);
88 rateFormatter.setMinimumFractionDigits(3);
89 countFormatter.setGroupingUsed(true);
90 countFormatter.setMaximumFractionDigits(0);
91 countFormatter.setMinimumFractionDigits(0);
92 }
93
94 public static String getCurrency(double number) {
95 return currencyFormatter.format(number);
96 }
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112 public static long getBytes(String size) {
113 return getBytes(size, SIZE_TOKENS, BASE);
114 }
115
116 public static long getBytes(String size, List<String> tokens, int base) {
117 Assert.notBlank(size);
118 for (int i = 0; i < tokens.size(); i++) {
119 String token = tokens.get(i);
120 long multiplier = (long) Math.pow(base, i);
121 if (StringUtils.endsWithIgnoreCase(size, token)) {
122 return getByteValue(size, token, multiplier);
123 }
124 }
125
126 return getByteValue(size, "", 1);
127 }
128
129 protected static long getByteValue(String time, String suffix, long multiplier) {
130 int len = StringUtils.length(time);
131 String substring = StringUtils.substring(time, 0, len - suffix.length());
132 Double value = new Double(substring);
133 value = value * multiplier;
134 return value.longValue();
135 }
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150 public static long getMillis(String time) {
151 return getMillis(time, TIME_TOKENS, TIME_MULTIPLIERS);
152 }
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167 public static int getMillisAsInt(String time) {
168 Long millis = getMillis(time);
169 if (millis <= Integer.MAX_VALUE) {
170 return millis.intValue();
171 } else {
172 throw Exceptions.illegalArgument("[%s] converts to [%s]. maximum allowable integer value is [%s]", time, millis, Integer.MAX_VALUE);
173 }
174 }
175
176 public static long getMillis(String time, List<String> tokens, List<Long> multipliers) {
177 Assert.notBlank(time);
178 Assert.isTrue(tokens.size() == multipliers.size());
179 for (int i = 0; i < tokens.size(); i++) {
180 String token = tokens.get(i);
181 long multiplier = multipliers.get(i);
182 if (StringUtils.endsWithIgnoreCase(time, token)) {
183 return getTimeValue(time, token, multiplier);
184 }
185 }
186
187 return getTimeValue(time, "", 1);
188 }
189
190 protected static long getTimeValue(String time, String suffix, long multiplier) {
191 int len = StringUtils.length(time);
192 String substring = StringUtils.substring(time, 0, len - suffix.length());
193 Double value = new Double(substring);
194 value = value * multiplier;
195 return value.longValue();
196 }
197
198
199
200
201 public static Date parseDate(String date) {
202 try {
203 synchronized (DATE_FORMATTER) {
204 return DATE_FORMATTER.parse(date);
205 }
206 } catch (ParseException e) {
207 throw new IllegalArgumentException("Can't parse [" + date + "]", e);
208 }
209 }
210
211
212
213
214 public static String dateAsString(long millis) {
215 return dateAsString(new Date(millis));
216 }
217
218
219
220
221 public static String dateAsString(Date date) {
222 synchronized (JAVA_UTIL_DATE_TO_STRING_FORMATTER) {
223 return JAVA_UTIL_DATE_TO_STRING_FORMATTER.format(date);
224 }
225 }
226
227
228
229
230 public static String dateAsString(long millis, String timezone) {
231 return dateAsString(new Date(millis), timezone);
232 }
233
234
235
236
237 public static String dateAsString(Date date, String timezone) {
238 SimpleDateFormat sdf = new SimpleDateFormat(JAVA_UTIL_DATE_TO_STRING_FORMAT);
239 sdf.setTimeZone(TimeZone.getTimeZone(timezone));
240 return sdf.format(date);
241 }
242
243
244
245
246 public static String getDate(long millis) {
247 return getDate(new Date(millis));
248 }
249
250
251
252
253 public static String getDate(Date date) {
254 synchronized (DATE_FORMATTER) {
255 return DATE_FORMATTER.format(date);
256 }
257 }
258
259
260
261
262 public static String getThroughputInSeconds(long millis, long count, String label) {
263 double seconds = millis / SECOND;
264 double countPerSecond = count / seconds;
265 synchronized (countFormatter) {
266 return countFormatter.format(countPerSecond) + " " + label;
267 }
268 }
269
270
271
272
273 public static String getRate(long millis, long bytes) {
274 return getRate(millis, bytes, rateFormatter);
275 }
276
277
278
279
280 public static String getRate(long millis, long bytes, NumberFormat rateFormatter) {
281 double seconds = millis / SECOND;
282 double bytesPerSecond = bytes / seconds;
283 Size bandwidthLevel = getSizeEnum(bytesPerSecond);
284 double transferRate = bytesPerSecond / bandwidthLevel.getValue();
285 synchronized (rateFormatter) {
286 return rateFormatter.format(transferRate) + " " + bandwidthLevel.getRateLabel();
287 }
288 }
289
290
291
292
293 public static String getCount(Map<?, ?> map) {
294 return getCount(map.keySet());
295 }
296
297
298
299
300 public static String getCount(Iterable<?> iterable) {
301 return getCount(Iterables.size(iterable));
302 }
303
304
305
306
307 public static String getCount(long count) {
308 synchronized (countFormatter) {
309 return countFormatter.format(count);
310 }
311 }
312
313
314
315
316
317 public static String getTime(long millis) {
318 return getTime(millis, timeFormatter);
319 }
320
321
322
323
324
325 public static String getTime(Stopwatch stopwatch) {
326 return getTime(stopwatch.elapsed(MILLISECONDS));
327 }
328
329
330
331
332
333 public static String getTime(long millis, NumberFormat formatter) {
334 long abs = Math.abs(millis);
335 synchronized (formatter) {
336 if (abs < SECOND) {
337 return millis + "ms";
338 } else if (abs < MINUTE) {
339 return formatter.format(millis / SECOND) + "s";
340 } else if (abs < HOUR) {
341 return formatter.format(millis / MINUTE) + "m";
342 } else if (abs < DAY) {
343 return formatter.format(millis / HOUR) + "h";
344 } else if (abs < YEAR) {
345 return formatter.format(millis / DAY) + "d";
346 } else {
347 return formatter.format(millis / YEAR) + "y";
348 }
349 }
350 }
351
352
353
354
355 public static String getSize(long bytes) {
356 return getSize(bytes, (Size) null);
357 }
358
359
360
361
362 public static String getIntegerSize(long bytes) {
363 return getIntegerSize(bytes, null);
364 }
365
366
367
368
369 public static String getIntegerSize(long bytes, final Size unitOfMeasure) {
370 Size uom = (unitOfMeasure == null) ? getSizeEnum(bytes) : unitOfMeasure;
371 StringBuilder sb = new StringBuilder();
372 synchronized (integerFormatter) {
373 sb.append(integerFormatter.format(bytes / (double) uom.getValue()));
374 }
375 sb.append(uom.getSizeLabel());
376 return sb.toString();
377 }
378
379
380
381
382 public static String getSize(long bytes, NumberFormat formatter) {
383 return getSize(bytes, null, formatter);
384 }
385
386
387
388
389 public static String getSize(long bytes, final Size unitOfMeasure, NumberFormat formatter) {
390 Size uom = (unitOfMeasure == null) ? getSizeEnum(bytes) : unitOfMeasure;
391 StringBuilder sb = new StringBuilder();
392 synchronized (formatter) {
393 sb.append(formatter.format(bytes / (double) uom.getValue()));
394 }
395 sb.append(uom.getSizeLabel());
396 return sb.toString();
397 }
398
399
400
401
402 public static String getSize(long bytes, Size unitOfMeasure) {
403 Size uom = (unitOfMeasure == null) ? getSizeEnum(bytes) : unitOfMeasure;
404 StringBuilder sb = new StringBuilder();
405 sb.append(getFormattedSize(bytes, uom));
406 sb.append(uom.getSizeLabel());
407 return sb.toString();
408 }
409
410 public static String getFormattedSize(long bytes, Size size) {
411 switch (size) {
412 case BYTE:
413 return bytes + "";
414 case KB:
415 case MB:
416 case GB:
417 synchronized (sizeFormatter) {
418 return sizeFormatter.format(bytes / (double) size.getValue());
419 }
420 default:
421 synchronized (largeSizeFormatter) {
422 return largeSizeFormatter.format(bytes / (double) size.getValue());
423 }
424 }
425 }
426
427 public static Size getSizeEnum(double bytes) {
428 bytes = Math.abs(bytes);
429 if (bytes < Size.KB.getValue()) {
430 return Size.BYTE;
431 } else if (bytes < Size.MB.getValue()) {
432 return Size.KB;
433 } else if (bytes < Size.GB.getValue()) {
434 return Size.MB;
435 } else if (bytes < Size.TB.getValue()) {
436 return Size.GB;
437 } else if (bytes < Size.PB.getValue()) {
438 return Size.TB;
439 } else if (bytes < Size.EB.getValue()) {
440 return Size.PB;
441 } else {
442 return Size.EB;
443 }
444 }
445
446 protected static final List<Long> getTimeMultipliers() {
447 List<Long> m = new ArrayList<Long>();
448 m.add(1L);
449 m.add(new Double(SECOND).longValue());
450 m.add(new Double(MINUTE).longValue());
451 m.add(new Double(HOUR).longValue());
452 m.add(new Double(DAY).longValue());
453 m.add(new Double(YEAR).longValue());
454 return m;
455 }
456 }