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