1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.lang3.time;
19
20 import static org.junit.jupiter.api.Assertions.assertArrayEquals;
21 import static org.junit.jupiter.api.Assertions.assertEquals;
22 import static org.junit.jupiter.api.Assertions.assertFalse;
23 import static org.junit.jupiter.api.Assertions.assertNotEquals;
24 import static org.junit.jupiter.api.Assertions.assertNotNull;
25 import static org.junit.jupiter.api.Assertions.assertThrows;
26 import static org.junit.jupiter.api.Assertions.assertTrue;
27
28 import java.lang.reflect.Constructor;
29 import java.lang.reflect.Modifier;
30 import java.time.Duration;
31 import java.util.Calendar;
32 import java.util.TimeZone;
33
34 import org.apache.commons.lang3.AbstractLangTest;
35 import org.junit.jupiter.api.Test;
36 import org.junitpioneer.jupiter.DefaultTimeZone;
37
38
39
40
41
42
43
44 public class DurationFormatUtilsTest extends AbstractLangTest {
45
46 private static final int FOUR_YEARS = 365 * 3 + 366;
47
48 private void assertEqualDuration(final String expected, final int[] start, final int[] end, final String format) {
49 assertEqualDuration(null, expected, start, end, format);
50 }
51
52 private void assertEqualDuration(final String message, final String expected, final int[] start, final int[] end, final String format) {
53 final Calendar cal1 = Calendar.getInstance();
54 cal1.set(start[0], start[1], start[2], start[3], start[4], start[5]);
55 cal1.set(Calendar.MILLISECOND, 0);
56 final Calendar cal2 = Calendar.getInstance();
57 cal2.set(end[0], end[1], end[2], end[3], end[4], end[5]);
58 cal2.set(Calendar.MILLISECOND, 0);
59 final long milli1 = cal1.getTime().getTime();
60 final long milli2 = cal2.getTime().getTime();
61 final String result = DurationFormatUtils.formatPeriod(milli1, milli2, format);
62 if (message == null) {
63 assertEquals(expected, result);
64 } else {
65 assertEquals(expected, result, message);
66 }
67 }
68
69 private void bruteForce(final int year, final int month, final int day, final String format, final int calendarType) {
70 final String msg = year + "-" + month + "-" + day + " to ";
71 final Calendar c = Calendar.getInstance();
72 c.set(year, month, day, 0, 0, 0);
73 final int[] array1 = { year, month, day, 0, 0, 0 };
74 final int[] array2 = { year, month, day, 0, 0, 0 };
75 for (int i=0; i < FOUR_YEARS; i++) {
76 array2[0] = c.get(Calendar.YEAR);
77 array2[1] = c.get(Calendar.MONTH);
78 array2[2] = c.get(Calendar.DAY_OF_MONTH);
79 final String tmpMsg = msg + array2[0] + "-" + array2[1] + "-" + array2[2] + " at ";
80 assertEqualDuration(tmpMsg + i, Integer.toString(i), array1, array2, format );
81 c.add(calendarType, 1);
82 }
83 }
84
85 private DurationFormatUtils.Token createTokenWithCount(final Object value, final int count) {
86 DurationFormatUtils.Token token = new DurationFormatUtils.Token(value, false, -1);
87 for (int i = 1; i < count; i++) {
88 token.increment();
89 }
90 return token;
91 }
92
93 @Test
94 public void testAlternatingLiteralOptionals() {
95 String format = "['d'dH'h'][m'm']['s's]['ms'S]";
96
97 assertEquals("d1",
98 DurationFormatUtils.formatDuration(Duration.ofDays(1).toMillis(), format));
99
100 assertEquals("1h",
101 DurationFormatUtils.formatDuration(Duration.ofHours(1).toMillis(), format));
102
103 assertEquals("1m",
104 DurationFormatUtils.formatDuration(Duration.ofMinutes(1).toMillis(), format));
105
106 assertEquals("s1",
107 DurationFormatUtils.formatDuration(Duration.ofSeconds(1).toMillis(), format));
108
109 assertEquals("ms001",
110 DurationFormatUtils.formatDuration(Duration.ofMillis(1).toMillis(), format));
111
112 assertEquals("d1s1",
113 DurationFormatUtils.formatDuration(Duration.ofDays(1).plusSeconds(1).toMillis(), format));
114
115 assertEquals("d11h",
116 DurationFormatUtils.formatDuration(Duration.ofDays(1).plusHours(1).toMillis(), format));
117
118 assertEquals("d11h1m",
119 DurationFormatUtils.formatDuration(Duration.ofDays(1).plusHours(1).plusMinutes(1).toMillis(), format));
120
121 assertEquals("d11h1ms1",
122 DurationFormatUtils.formatDuration(Duration.ofDays(1).plusHours(1).plusMinutes(1).plusSeconds(1).toMillis(), format));
123
124 assertEquals("d11h1ms1ms001",
125 DurationFormatUtils.formatDuration(Duration.ofDays(1).plusHours(1).plusMinutes(1).plusSeconds(1).plusMillis(1).toMillis(), format));
126
127 }
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159 @Test
160 @DefaultTimeZone(TimeZones.GMT_ID)
161 public void testEdgeDurations() {
162
163 TimeZone.setDefault(FastTimeZone.getGmtTimeZone());
164 assertEqualDuration("01", new int[] { 2006, 0, 15, 0, 0, 0 },
165 new int[] { 2006, 2, 10, 0, 0, 0 }, "MM");
166 assertEqualDuration("12", new int[] { 2005, 0, 15, 0, 0, 0 },
167 new int[] { 2006, 0, 15, 0, 0, 0 }, "MM");
168 assertEqualDuration("12", new int[] { 2005, 0, 15, 0, 0, 0 },
169 new int[] { 2006, 0, 16, 0, 0, 0 }, "MM");
170 assertEqualDuration("11", new int[] { 2005, 0, 15, 0, 0, 0 },
171 new int[] { 2006, 0, 14, 0, 0, 0 }, "MM");
172
173 assertEqualDuration("01 26", new int[] { 2006, 0, 15, 0, 0, 0 },
174 new int[] { 2006, 2, 10, 0, 0, 0 }, "MM dd");
175 assertEqualDuration("54", new int[] { 2006, 0, 15, 0, 0, 0 },
176 new int[] { 2006, 2, 10, 0, 0, 0 }, "dd");
177
178 assertEqualDuration("09 12", new int[] { 2006, 1, 20, 0, 0, 0 },
179 new int[] { 2006, 11, 4, 0, 0, 0 }, "MM dd");
180 assertEqualDuration("287", new int[] { 2006, 1, 20, 0, 0, 0 },
181 new int[] { 2006, 11, 4, 0, 0, 0 }, "dd");
182
183 assertEqualDuration("11 30", new int[] { 2006, 0, 2, 0, 0, 0 },
184 new int[] { 2007, 0, 1, 0, 0, 0 }, "MM dd");
185 assertEqualDuration("364", new int[] { 2006, 0, 2, 0, 0, 0 },
186 new int[] { 2007, 0, 1, 0, 0, 0 }, "dd");
187
188 assertEqualDuration("12 00", new int[] { 2006, 0, 1, 0, 0, 0 },
189 new int[] { 2007, 0, 1, 0, 0, 0 }, "MM dd");
190 assertEqualDuration("365", new int[] { 2006, 0, 1, 0, 0, 0 },
191 new int[] { 2007, 0, 1, 0, 0, 0 }, "dd");
192
193 assertEqualDuration("31", new int[] { 2006, 0, 1, 0, 0, 0 },
194 new int[] { 2006, 1, 1, 0, 0, 0 }, "dd");
195
196 assertEqualDuration("92", new int[] { 2005, 9, 1, 0, 0, 0 },
197 new int[] { 2006, 0, 1, 0, 0, 0 }, "dd");
198 assertEqualDuration("77", new int[] { 2005, 9, 16, 0, 0, 0 },
199 new int[] { 2006, 0, 1, 0, 0, 0 }, "dd");
200
201
202 assertEqualDuration("136", new int[] { 2005, 9, 16, 0, 0, 0 },
203 new int[] { 2006, 2, 1, 0, 0, 0 }, "dd");
204
205 assertEqualDuration("136", new int[] { 2004, 9, 16, 0, 0, 0 },
206 new int[] { 2005, 2, 1, 0, 0, 0 }, "dd");
207
208 assertEqualDuration("137", new int[] { 2003, 9, 16, 0, 0, 0 },
209 new int[] { 2004, 2, 1, 0, 0, 0 }, "dd");
210
211 assertEqualDuration("135", new int[] { 2003, 9, 16, 0, 0, 0 },
212 new int[] { 2004, 1, 28, 0, 0, 0 }, "dd");
213
214 assertEqualDuration("364", new int[] { 2007, 0, 2, 0, 0, 0 },
215 new int[] { 2008, 0, 1, 0, 0, 0 }, "dd");
216 assertEqualDuration("729", new int[] { 2006, 0, 2, 0, 0, 0 },
217 new int[] { 2008, 0, 1, 0, 0, 0 }, "dd");
218
219 assertEqualDuration("365", new int[] { 2007, 2, 2, 0, 0, 0 },
220 new int[] { 2008, 2, 1, 0, 0, 0 }, "dd");
221 assertEqualDuration("333", new int[] { 2007, 1, 2, 0, 0, 0 },
222 new int[] { 2008, 0, 1, 0, 0, 0 }, "dd");
223
224 assertEqualDuration("28", new int[] { 2008, 1, 2, 0, 0, 0 },
225 new int[] { 2008, 2, 1, 0, 0, 0 }, "dd");
226 assertEqualDuration("393", new int[] { 2007, 1, 2, 0, 0, 0 },
227 new int[] { 2008, 2, 1, 0, 0, 0 }, "dd");
228
229 assertEqualDuration("369", new int[] { 2004, 0, 29, 0, 0, 0 },
230 new int[] { 2005, 1, 1, 0, 0, 0 }, "dd");
231
232 assertEqualDuration("338", new int[] { 2004, 1, 29, 0, 0, 0 },
233 new int[] { 2005, 1, 1, 0, 0, 0 }, "dd");
234
235 assertEqualDuration("28", new int[] { 2004, 2, 8, 0, 0, 0 },
236 new int[] { 2004, 3, 5, 0, 0, 0 }, "dd");
237
238 assertEqualDuration("48", new int[] { 1992, 1, 29, 0, 0, 0 },
239 new int[] { 1996, 1, 29, 0, 0, 0 }, "M");
240
241
242
243
244 assertEqualDuration("11", new int[] { 1996, 1, 29, 0, 0, 0 },
245 new int[] { 1997, 1, 28, 0, 0, 0 }, "M");
246
247 assertEqualDuration("11 28", new int[] { 1996, 1, 29, 0, 0, 0 },
248 new int[] { 1997, 1, 28, 0, 0, 0 }, "M d");
249
250 }
251
252 @Test
253 public void testEmptyOptionals() {
254 assertEquals(
255 "",
256 DurationFormatUtils.formatDuration(0L, "[d'd'][H'h'][m'm'][s's']"));
257 assertEquals(
258 "",
259 DurationFormatUtils.formatDuration(0L, "['d''h''m''s's]"));
260 }
261
262 @Test
263 public void testFormatDuration() {
264 long duration = 0;
265 assertEquals("0", DurationFormatUtils.formatDuration(duration, "y"));
266 assertEquals("0", DurationFormatUtils.formatDuration(duration, "M"));
267 assertEquals("0", DurationFormatUtils.formatDuration(duration, "d"));
268 assertEquals("0", DurationFormatUtils.formatDuration(duration, "H"));
269 assertEquals("0", DurationFormatUtils.formatDuration(duration, "m"));
270 assertEquals("0", DurationFormatUtils.formatDuration(duration, "s"));
271 assertEquals("0", DurationFormatUtils.formatDuration(duration, "S"));
272 assertEquals("0000", DurationFormatUtils.formatDuration(duration, "SSSS"));
273 assertEquals("0000", DurationFormatUtils.formatDuration(duration, "yyyy"));
274 assertEquals("0000", DurationFormatUtils.formatDuration(duration, "yyMM"));
275
276 duration = 60 * 1000;
277 assertEquals("0", DurationFormatUtils.formatDuration(duration, "y"));
278 assertEquals("0", DurationFormatUtils.formatDuration(duration, "M"));
279 assertEquals("0", DurationFormatUtils.formatDuration(duration, "d"));
280 assertEquals("0", DurationFormatUtils.formatDuration(duration, "H"));
281 assertEquals("1", DurationFormatUtils.formatDuration(duration, "m"));
282 assertEquals("60", DurationFormatUtils.formatDuration(duration, "s"));
283 assertEquals("60000", DurationFormatUtils.formatDuration(duration, "S"));
284 assertEquals("01:00", DurationFormatUtils.formatDuration(duration, "mm:ss"));
285
286 final Calendar base = Calendar.getInstance();
287 base.set(2000, Calendar.JANUARY, 1, 0, 0, 0);
288 base.set(Calendar.MILLISECOND, 0);
289
290 final Calendar cal = Calendar.getInstance();
291 cal.set(2003, Calendar.FEBRUARY, 1, 0, 0, 0);
292 cal.set(Calendar.MILLISECOND, 0);
293 duration = cal.getTime().getTime() - base.getTime().getTime();
294
295
296 final int days = 366 + 365 + 365 + 31;
297 assertEquals("0 0 " + days, DurationFormatUtils.formatDuration(duration, "y M d"));
298 }
299
300 @Test
301 public void testFormatDurationHMS() {
302 long time = 0;
303 assertEquals("00:00:00.000", DurationFormatUtils.formatDurationHMS(time));
304
305 time = 1;
306 assertEquals("00:00:00.001", DurationFormatUtils.formatDurationHMS(time));
307
308 time = 15;
309 assertEquals("00:00:00.015", DurationFormatUtils.formatDurationHMS(time));
310
311 time = 165;
312 assertEquals("00:00:00.165", DurationFormatUtils.formatDurationHMS(time));
313
314 time = 1675;
315 assertEquals("00:00:01.675", DurationFormatUtils.formatDurationHMS(time));
316
317 time = 13465;
318 assertEquals("00:00:13.465", DurationFormatUtils.formatDurationHMS(time));
319
320 time = 72789;
321 assertEquals("00:01:12.789", DurationFormatUtils.formatDurationHMS(time));
322
323 time = 12789 + 32 * 60000;
324 assertEquals("00:32:12.789", DurationFormatUtils.formatDurationHMS(time));
325
326 time = 12789 + 62 * 60000;
327 assertEquals("01:02:12.789", DurationFormatUtils.formatDurationHMS(time));
328 }
329
330 @Test
331 public void testFormatDurationISO() {
332 assertEquals("P0Y0M0DT0H0M0.000S", DurationFormatUtils.formatDurationISO(0L));
333 assertEquals("P0Y0M0DT0H0M0.001S", DurationFormatUtils.formatDurationISO(1L));
334 assertEquals("P0Y0M0DT0H0M0.010S", DurationFormatUtils.formatDurationISO(10L));
335 assertEquals("P0Y0M0DT0H0M0.100S", DurationFormatUtils.formatDurationISO(100L));
336 assertEquals("P0Y0M0DT0H1M15.321S", DurationFormatUtils.formatDurationISO(75321L));
337 }
338
339
340
341
342 @Test
343 public void testFormatDurationPluralWords() {
344 final long oneSecond = 1000;
345 final long oneMinute = oneSecond * 60;
346 final long oneHour = oneMinute * 60;
347 final long oneDay = oneHour * 24;
348 String text;
349
350 text = DurationFormatUtils.formatDurationWords(oneSecond, false, false);
351 assertEquals("0 days 0 hours 0 minutes 1 second", text);
352 text = DurationFormatUtils.formatDurationWords(oneSecond * 2, false, false);
353 assertEquals("0 days 0 hours 0 minutes 2 seconds", text);
354 text = DurationFormatUtils.formatDurationWords(oneSecond * 11, false, false);
355 assertEquals("0 days 0 hours 0 minutes 11 seconds", text);
356
357 text = DurationFormatUtils.formatDurationWords(oneMinute, false, false);
358 assertEquals("0 days 0 hours 1 minute 0 seconds", text);
359 text = DurationFormatUtils.formatDurationWords(oneMinute * 2, false, false);
360 assertEquals("0 days 0 hours 2 minutes 0 seconds", text);
361 text = DurationFormatUtils.formatDurationWords(oneMinute * 11, false, false);
362 assertEquals("0 days 0 hours 11 minutes 0 seconds", text);
363 text = DurationFormatUtils.formatDurationWords(oneMinute + oneSecond, false, false);
364 assertEquals("0 days 0 hours 1 minute 1 second", text);
365
366 text = DurationFormatUtils.formatDurationWords(oneHour, false, false);
367 assertEquals("0 days 1 hour 0 minutes 0 seconds", text);
368 text = DurationFormatUtils.formatDurationWords(oneHour * 2, false, false);
369 assertEquals("0 days 2 hours 0 minutes 0 seconds", text);
370 text = DurationFormatUtils.formatDurationWords(oneHour * 11, false, false);
371 assertEquals("0 days 11 hours 0 minutes 0 seconds", text);
372 text = DurationFormatUtils.formatDurationWords(oneHour + oneMinute + oneSecond, false, false);
373 assertEquals("0 days 1 hour 1 minute 1 second", text);
374
375 text = DurationFormatUtils.formatDurationWords(oneDay, false, false);
376 assertEquals("1 day 0 hours 0 minutes 0 seconds", text);
377 text = DurationFormatUtils.formatDurationWords(oneDay * 2, false, false);
378 assertEquals("2 days 0 hours 0 minutes 0 seconds", text);
379 text = DurationFormatUtils.formatDurationWords(oneDay * 11, false, false);
380 assertEquals("11 days 0 hours 0 minutes 0 seconds", text);
381 text = DurationFormatUtils.formatDurationWords(oneDay + oneHour + oneMinute + oneSecond, false, false);
382 assertEquals("1 day 1 hour 1 minute 1 second", text);
383 }
384
385 @Test
386 public void testFormatDurationWords() {
387 String text;
388
389 text = DurationFormatUtils.formatDurationWords(50 * 1000, true, false);
390 assertEquals("50 seconds", text);
391 text = DurationFormatUtils.formatDurationWords(65 * 1000, true, false);
392 assertEquals("1 minute 5 seconds", text);
393 text = DurationFormatUtils.formatDurationWords(120 * 1000, true, false);
394 assertEquals("2 minutes 0 seconds", text);
395 text = DurationFormatUtils.formatDurationWords(121 * 1000, true, false);
396 assertEquals("2 minutes 1 second", text);
397 text = DurationFormatUtils.formatDurationWords(72 * 60 * 1000, true, false);
398 assertEquals("1 hour 12 minutes 0 seconds", text);
399 text = DurationFormatUtils.formatDurationWords(24 * 60 * 60 * 1000, true, false);
400 assertEquals("1 day 0 hours 0 minutes 0 seconds", text);
401
402 text = DurationFormatUtils.formatDurationWords(50 * 1000, true, true);
403 assertEquals("50 seconds", text);
404 text = DurationFormatUtils.formatDurationWords(65 * 1000, true, true);
405 assertEquals("1 minute 5 seconds", text);
406 text = DurationFormatUtils.formatDurationWords(120 * 1000, true, true);
407 assertEquals("2 minutes", text);
408 text = DurationFormatUtils.formatDurationWords(121 * 1000, true, true);
409 assertEquals("2 minutes 1 second", text);
410 text = DurationFormatUtils.formatDurationWords(72 * 60 * 1000, true, true);
411 assertEquals("1 hour 12 minutes", text);
412 text = DurationFormatUtils.formatDurationWords(24 * 60 * 60 * 1000, true, true);
413 assertEquals("1 day", text);
414
415 text = DurationFormatUtils.formatDurationWords(50 * 1000, false, true);
416 assertEquals("0 days 0 hours 0 minutes 50 seconds", text);
417 text = DurationFormatUtils.formatDurationWords(65 * 1000, false, true);
418 assertEquals("0 days 0 hours 1 minute 5 seconds", text);
419 text = DurationFormatUtils.formatDurationWords(120 * 1000, false, true);
420 assertEquals("0 days 0 hours 2 minutes", text);
421 text = DurationFormatUtils.formatDurationWords(121 * 1000, false, true);
422 assertEquals("0 days 0 hours 2 minutes 1 second", text);
423 text = DurationFormatUtils.formatDurationWords(72 * 60 * 1000, false, true);
424 assertEquals("0 days 1 hour 12 minutes", text);
425 text = DurationFormatUtils.formatDurationWords(24 * 60 * 60 * 1000, false, true);
426 assertEquals("1 day", text);
427
428 text = DurationFormatUtils.formatDurationWords(50 * 1000, false, false);
429 assertEquals("0 days 0 hours 0 minutes 50 seconds", text);
430 text = DurationFormatUtils.formatDurationWords(65 * 1000, false, false);
431 assertEquals("0 days 0 hours 1 minute 5 seconds", text);
432 text = DurationFormatUtils.formatDurationWords(120 * 1000, false, false);
433 assertEquals("0 days 0 hours 2 minutes 0 seconds", text);
434 text = DurationFormatUtils.formatDurationWords(121 * 1000, false, false);
435 assertEquals("0 days 0 hours 2 minutes 1 second", text);
436 text = DurationFormatUtils.formatDurationWords(72 * 60 * 1000, false, false);
437 assertEquals("0 days 1 hour 12 minutes 0 seconds", text);
438 text = DurationFormatUtils.formatDurationWords(24 * 60 * 60 * 1000 + 72 * 60 * 1000, false, false);
439 assertEquals("1 day 1 hour 12 minutes 0 seconds", text);
440 text = DurationFormatUtils.formatDurationWords(2 * 24 * 60 * 60 * 1000 + 72 * 60 * 1000, false, false);
441 assertEquals("2 days 1 hour 12 minutes 0 seconds", text);
442 for (int i = 2; i < 31; i++) {
443 text = DurationFormatUtils.formatDurationWords(i * 24 * 60 * 60 * 1000L, false, false);
444 assertEquals(i + " days 0 hours 0 minutes 0 seconds", text);
445 }
446 }
447
448
449 @Test
450 public void testFormatNegativeDuration() {
451 assertThrows(IllegalArgumentException.class, () -> DurationFormatUtils.formatDuration(-5000, "S", true));
452 }
453
454 @Test
455 public void testFormatNegativeDurationHMS() {
456 assertThrows(IllegalArgumentException.class, () -> DurationFormatUtils.formatDurationHMS(-5000));
457 }
458
459 @Test
460 public void testFormatNegativeDurationISO() {
461 assertThrows(IllegalArgumentException.class, () -> DurationFormatUtils.formatDurationISO(-5000));
462 }
463
464 @Test
465 public void testFormatNegativeDurationWords() {
466 assertThrows(IllegalArgumentException.class, () -> DurationFormatUtils.formatDurationWords(-5000, true, true));
467 }
468
469 @Test
470 public void testFormatPeriod() {
471 final Calendar cal1970 = Calendar.getInstance();
472 cal1970.set(1970, Calendar.JANUARY, 1, 0, 0, 0);
473 cal1970.set(Calendar.MILLISECOND, 0);
474 final long time1970 = cal1970.getTime().getTime();
475
476 assertEquals("0", DurationFormatUtils.formatPeriod(time1970, time1970, "y"));
477 assertEquals("0", DurationFormatUtils.formatPeriod(time1970, time1970, "M"));
478 assertEquals("0", DurationFormatUtils.formatPeriod(time1970, time1970, "d"));
479 assertEquals("0", DurationFormatUtils.formatPeriod(time1970, time1970, "H"));
480 assertEquals("0", DurationFormatUtils.formatPeriod(time1970, time1970, "m"));
481 assertEquals("0", DurationFormatUtils.formatPeriod(time1970, time1970, "s"));
482 assertEquals("0", DurationFormatUtils.formatPeriod(time1970, time1970, "S"));
483 assertEquals("0000", DurationFormatUtils.formatPeriod(time1970, time1970, "SSSS"));
484 assertEquals("0000", DurationFormatUtils.formatPeriod(time1970, time1970, "yyyy"));
485 assertEquals("0000", DurationFormatUtils.formatPeriod(time1970, time1970, "yyMM"));
486
487 long time = time1970 + 60 * 1000;
488 assertEquals("0", DurationFormatUtils.formatPeriod(time1970, time, "y"));
489 assertEquals("0", DurationFormatUtils.formatPeriod(time1970, time, "M"));
490 assertEquals("0", DurationFormatUtils.formatPeriod(time1970, time, "d"));
491 assertEquals("0", DurationFormatUtils.formatPeriod(time1970, time, "H"));
492 assertEquals("1", DurationFormatUtils.formatPeriod(time1970, time, "m"));
493 assertEquals("60", DurationFormatUtils.formatPeriod(time1970, time, "s"));
494 assertEquals("60000", DurationFormatUtils.formatPeriod(time1970, time, "S"));
495 assertEquals("01:00", DurationFormatUtils.formatPeriod(time1970, time, "mm:ss"));
496
497 final Calendar cal = Calendar.getInstance();
498 cal.set(1973, Calendar.JULY, 1, 0, 0, 0);
499 cal.set(Calendar.MILLISECOND, 0);
500 time = cal.getTime().getTime();
501 assertEquals("36", DurationFormatUtils.formatPeriod(time1970, time, "yM"));
502 assertEquals("3 years 6 months", DurationFormatUtils.formatPeriod(time1970, time, "y' years 'M' months'"));
503 assertEquals("03/06", DurationFormatUtils.formatPeriod(time1970, time, "yy/MM"));
504
505 cal.set(1973, Calendar.NOVEMBER, 1, 0, 0, 0);
506 cal.set(Calendar.MILLISECOND, 0);
507 time = cal.getTime().getTime();
508 assertEquals("310", DurationFormatUtils.formatPeriod(time1970, time, "yM"));
509 assertEquals("3 years 10 months", DurationFormatUtils.formatPeriod(time1970, time, "y' years 'M' months'"));
510 assertEquals("03/10", DurationFormatUtils.formatPeriod(time1970, time, "yy/MM"));
511
512 cal.set(1974, Calendar.JANUARY, 1, 0, 0, 0);
513 cal.set(Calendar.MILLISECOND, 0);
514 time = cal.getTime().getTime();
515 assertEquals("40", DurationFormatUtils.formatPeriod(time1970, time, "yM"));
516 assertEquals("4 years 0 months", DurationFormatUtils.formatPeriod(time1970, time, "y' years 'M' months'"));
517 assertEquals("04/00", DurationFormatUtils.formatPeriod(time1970, time, "yy/MM"));
518 assertEquals("48", DurationFormatUtils.formatPeriod(time1970, time, "M"));
519 assertEquals("48", DurationFormatUtils.formatPeriod(time1970, time, "MM"));
520 assertEquals("048", DurationFormatUtils.formatPeriod(time1970, time, "MMM"));
521 }
522
523 @Test
524 public void testFormatPeriodeStartGreaterEnd() {
525 assertThrows(IllegalArgumentException.class, () -> DurationFormatUtils.formatPeriod(5000, 2500, "yy/MM"));
526 }
527
528 @SuppressWarnings("deprecation")
529 @Test
530 public void testFormatPeriodISO() {
531 final TimeZone timeZone = TimeZone.getTimeZone("GMT-3");
532 final Calendar base = Calendar.getInstance(timeZone);
533 base.set(1970, Calendar.JANUARY, 1, 0, 0, 0);
534 base.set(Calendar.MILLISECOND, 0);
535
536 final Calendar cal = Calendar.getInstance(timeZone);
537 cal.set(2002, Calendar.FEBRUARY, 23, 9, 11, 12);
538 cal.set(Calendar.MILLISECOND, 1);
539 String text;
540
541 text = DateFormatUtils.format(cal, DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.getPattern(), timeZone);
542 assertEquals("2002-02-23T09:11:12-03:00", text);
543
544 text = DurationFormatUtils.formatPeriod(base.getTime().getTime(), cal.getTime().getTime(),
545 DurationFormatUtils.ISO_EXTENDED_FORMAT_PATTERN, false, timeZone);
546 assertEquals("P32Y1M22DT9H11M12.001S", text);
547
548 cal.set(1971, Calendar.FEBRUARY, 3, 10, 30, 0);
549 cal.set(Calendar.MILLISECOND, 0);
550 text = DurationFormatUtils.formatPeriod(base.getTime().getTime(), cal.getTime().getTime(),
551 DurationFormatUtils.ISO_EXTENDED_FORMAT_PATTERN, false, timeZone);
552 assertEquals("P1Y1M2DT10H30M0.000S", text);
553
554
555 }
556
557 @Test
558 public void testFormatPeriodISOMethod() {
559 assertEquals("P0Y0M0DT0H0M0.000S", DurationFormatUtils.formatPeriodISO(0L, 0L));
560 assertEquals("P0Y0M0DT0H0M1.000S", DurationFormatUtils.formatPeriodISO(0L, 1000L));
561 assertEquals("P0Y0M0DT0H1M1.000S", DurationFormatUtils.formatPeriodISO(0L, 61000L));
562 }
563
564 @Test
565 public void testFormatPeriodISOStartGreaterEnd() {
566 assertThrows(IllegalArgumentException.class, () -> DurationFormatUtils.formatPeriodISO(5000, 2000));
567 }
568
569
570 @Test
571 public void testJiraLang281() {
572 assertEqualDuration("09", new int[] { 2005, 11, 31, 0, 0, 0 },
573 new int[] { 2006, 9, 6, 0, 0, 0 }, "MM");
574 }
575
576
577
578
579
580
581
582
583
584
585
586 @Test
587 public void testLANG815() {
588 final Calendar calendar = Calendar.getInstance();
589 calendar.set(2012, Calendar.JULY, 30, 0, 0, 0);
590 final long startMillis = calendar.getTimeInMillis();
591
592 calendar.set(2012, Calendar.SEPTEMBER, 8);
593 final long endMillis = calendar.getTimeInMillis();
594
595 assertEquals("1 9", DurationFormatUtils.formatPeriod(startMillis, endMillis, "M d"));
596 }
597
598 @Test
599 public void testLANG981() {
600 assertThrows(IllegalArgumentException.class, () -> DurationFormatUtils.lexx("'yMdHms''S"));
601 }
602 @Test
603 public void testLANG982() {
604 assertEquals("61.999", DurationFormatUtils.formatDuration(61999, "s.S"));
605 assertEquals("1 1999", DurationFormatUtils.formatDuration(61999, "m S"));
606 assertEquals("61.999", DurationFormatUtils.formatDuration(61999, "s.SSS"));
607 assertEquals("1 1999", DurationFormatUtils.formatDuration(61999, "m SSS"));
608 assertEquals("61.0999", DurationFormatUtils.formatDuration(61999, "s.SSSS"));
609 assertEquals("1 1999", DurationFormatUtils.formatDuration(61999, "m SSSS"));
610 assertEquals("61.00999", DurationFormatUtils.formatDuration(61999, "s.SSSSS"));
611 assertEquals("1 01999", DurationFormatUtils.formatDuration(61999, "m SSSSS"));
612 }
613
614
615 @Test
616 public void testLANG984() {
617 assertEquals("0", DurationFormatUtils.formatDuration(0, "S"));
618 assertEquals(Integer.toString(Integer.MAX_VALUE), DurationFormatUtils.formatDuration(Integer.MAX_VALUE, "S"));
619 long maxIntPlus=Integer.MAX_VALUE;
620 maxIntPlus++;
621 assertEquals(Long.toString(maxIntPlus), DurationFormatUtils.formatDuration(maxIntPlus, "S"));
622 assertEquals(Long.toString(Long.MAX_VALUE), DurationFormatUtils.formatDuration(Long.MAX_VALUE, "S"));
623 }
624
625 @Test
626 public void testLexx() {
627
628 assertArrayEquals(new DurationFormatUtils.Token[]{
629 createTokenWithCount(DurationFormatUtils.y, 1),
630 createTokenWithCount(DurationFormatUtils.M, 1),
631 createTokenWithCount(DurationFormatUtils.d, 1),
632 createTokenWithCount(DurationFormatUtils.H, 1),
633 createTokenWithCount(DurationFormatUtils.m, 1),
634 createTokenWithCount(DurationFormatUtils.s, 1),
635 createTokenWithCount(DurationFormatUtils.S, 1)}, DurationFormatUtils.lexx("yMdHmsS"));
636
637
638 assertArrayEquals(new DurationFormatUtils.Token[]{
639 createTokenWithCount(DurationFormatUtils.H, 2),
640 createTokenWithCount(new StringBuilder(":"), 1),
641 createTokenWithCount(DurationFormatUtils.m, 2),
642 createTokenWithCount(new StringBuilder(":"), 1),
643 createTokenWithCount(DurationFormatUtils.s, 2),
644 createTokenWithCount(new StringBuilder("."), 1),
645 createTokenWithCount(DurationFormatUtils.S, 3)}, DurationFormatUtils.lexx("HH:mm:ss.SSS"));
646
647
648 assertArrayEquals(new DurationFormatUtils.Token[]{
649 createTokenWithCount(new StringBuilder("P"), 1),
650 createTokenWithCount(DurationFormatUtils.y, 4),
651 createTokenWithCount(new StringBuilder("Y"), 1),
652 createTokenWithCount(DurationFormatUtils.M, 1),
653 createTokenWithCount(new StringBuilder("M"), 1),
654 createTokenWithCount(DurationFormatUtils.d, 1),
655 createTokenWithCount(new StringBuilder("DT"), 1),
656 createTokenWithCount(DurationFormatUtils.H, 1),
657 createTokenWithCount(new StringBuilder("H"), 1),
658 createTokenWithCount(DurationFormatUtils.m, 1),
659 createTokenWithCount(new StringBuilder("M"), 1),
660 createTokenWithCount(DurationFormatUtils.s, 1),
661 createTokenWithCount(new StringBuilder("."), 1),
662 createTokenWithCount(DurationFormatUtils.S, 3),
663 createTokenWithCount(new StringBuilder("S"), 1)}, DurationFormatUtils
664 .lexx(DurationFormatUtils.ISO_EXTENDED_FORMAT_PATTERN));
665
666
667 final DurationFormatUtils.Token token = createTokenWithCount(DurationFormatUtils.y, 4);
668 assertNotEquals(token, new Object(), "Token equal to non-Token class. ");
669 assertNotEquals(token, createTokenWithCount(new Object(), 1), "Token equal to Token with wrong value class. ");
670 assertNotEquals(token, createTokenWithCount(DurationFormatUtils.y, 1), "Token equal to Token with different count. ");
671 final DurationFormatUtils.Token numToken = createTokenWithCount(Integer.valueOf(1), 4);
672 assertEquals(numToken, numToken, "Token with Number value not equal to itself. ");
673 }
674
675 @Test
676 public void testLiteralPrefixOptionalToken() {
677 assertEquals(
678 DurationFormatUtils.formatDuration(10000L, "s's'"),
679 DurationFormatUtils.formatDuration(10000L, "['['d']']['<'H'>']['{'m'}']s's'"));
680 assertEquals(
681 DurationFormatUtils.formatDuration(10000L, "s's'"),
682 DurationFormatUtils.formatDuration(10000L, "['{'m'}']s's'"));
683 }
684
685
686 @Test
687 public void testLowDurations() {
688 for (int hr=0; hr < 24; hr++) {
689 for (int min=0; min < 60; min++) {
690 for (int sec=0; sec < 60; sec++) {
691 assertEqualDuration(hr + ":" + min + ":" + sec,
692 new int[] { 2000, 0, 1, 0, 0, 0, 0 },
693 new int[] { 2000, 0, 1, hr, min, sec },
694 "H:m:s"
695 );
696 }
697 }
698 }
699 }
700
701 @Test
702 public void testMultipleOptionalBlocks() {
703
704 assertEquals(
705 DurationFormatUtils.formatDuration(Duration.ofHours(1).toMillis(), "'[['H']]'"),
706 DurationFormatUtils.formatDuration(Duration.ofHours(1).toMillis(), "['{'d'}']['[['H']]']"));
707
708 assertEquals(
709 DurationFormatUtils.formatDuration(Duration.ofDays(1).toMillis(), "['{'d'}']"),
710 DurationFormatUtils.formatDuration(Duration.ofDays(1).toMillis(), "['{'d'}']['['H']']"));
711 }
712
713 @Test
714 public void testOptionalLiteralSpecialCharacters() {
715 assertEquals(
716 DurationFormatUtils.formatDuration(10000L, "s's'"),
717 DurationFormatUtils.formatDuration(10000L, "['['m']']s's'"));
718 }
719
720 @Test
721 public void testOptionalToken() {
722
723
724 assertEquals(
725 DurationFormatUtils.formatDuration(915361000L, "d'd'H'h'm'm's's'"),
726 DurationFormatUtils.formatDuration(915361000L, "[d'd'H'h'm'm']s's'"));
727
728 assertEquals(
729 DurationFormatUtils.formatDuration(9153610L, "H'h'm'm's's'"),
730 DurationFormatUtils.formatDuration(9153610L, "[d'd'H'h'm'm']s's'"));
731
732 assertEquals(
733 DurationFormatUtils.formatDuration(915361L, "m'm's's'"),
734 DurationFormatUtils.formatDuration(915361L, "[d'd'H'h'm'm']s's'"));
735
736 assertEquals(
737 DurationFormatUtils.formatDuration(9153L, "s's'"),
738 DurationFormatUtils.formatDuration(9153L, "[d'd'H'h'm'm']s's'"));
739
740 assertEquals(
741 DurationFormatUtils.formatDuration(9153L, "s's'"),
742 DurationFormatUtils.formatDuration(9153L, "[d'd'H'h'm'm']s's'"));
743
744 assertEquals(
745 DurationFormatUtils.formatPeriod(9153610L, 915361000L, "d'd'H'h'm'm's's'"),
746 DurationFormatUtils.formatPeriod(9153610L, 915361000L, "[d'd'H'h'm'm']s's'"));
747
748 assertEquals(
749 DurationFormatUtils.formatPeriod(915361L, 9153610L, "H'h'm'm's's'"),
750 DurationFormatUtils.formatPeriod(915361L, 9153610L, "[d'd'H'h'm'm']s's'"));
751
752 assertEquals(
753 DurationFormatUtils.formatPeriod(9153L, 915361L, "m'm's's'"),
754 DurationFormatUtils.formatPeriod(9153L, 915361L, "[d'd'H'h'm'm']s's'"));
755
756 assertEquals(
757 DurationFormatUtils.formatPeriod(0L, 9153L, "s's'"),
758 DurationFormatUtils.formatPeriod(0L, 9153L, "[d'd'H'h'm'm']s's'"));
759
760
761
762 assertEquals("2h32m33s610ms", DurationFormatUtils.formatDuration(9153610L, "[d'd'H'h'm'm's's']S'ms'"));
763
764 assertEquals("15m15s361ms", DurationFormatUtils.formatDuration(915361L, "[d'd'H'h'm'm's's']S'ms'"));
765
766 assertEquals("9s153ms", DurationFormatUtils.formatDuration(9153L, "[d'd'H'h'm'm's's']S'ms'"));
767
768 assertEquals("915ms", DurationFormatUtils.formatDuration(915L, "[d'd'H'h'm'm's's']S'ms'"));
769
770
771
772 assertEquals(
773 DurationFormatUtils.formatPeriod(915361L, 9153610L, "H'h''h2'm'm's's'"),
774 DurationFormatUtils.formatPeriod(915361L, 9153610L, "[d'd''d2'H'h''h2'm'm']s's'"));
775 }
776
777 @Test
778 public void testUnmatchedOptionalTokens() {
779 assertThrows(IllegalArgumentException.class, () -> DurationFormatUtils.formatDuration(1, "[s"));
780 assertThrows(IllegalArgumentException.class, () -> DurationFormatUtils.formatDuration(1, "[[s"));
781 assertThrows(IllegalArgumentException.class, () -> DurationFormatUtils.formatDuration(1, "[s]]"));
782 }
783 }