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