1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.lang3.time;
18
19 import static org.apache.commons.lang3.LangAssertions.assertIllegalArgumentException;
20 import static org.junit.jupiter.api.Assertions.assertEquals;
21 import static org.junit.jupiter.api.Assertions.assertNotEquals;
22 import static org.junit.jupiter.api.Assertions.assertTrue;
23
24 import java.io.Serializable;
25 import java.text.FieldPosition;
26 import java.text.SimpleDateFormat;
27 import java.util.Calendar;
28 import java.util.Date;
29 import java.util.GregorianCalendar;
30 import java.util.Locale;
31 import java.util.TimeZone;
32
33 import org.apache.commons.lang3.AbstractLangTest;
34 import org.apache.commons.lang3.SerializationUtils;
35 import org.junit.jupiter.api.Test;
36 import org.junitpioneer.jupiter.DefaultLocale;
37 import org.junitpioneer.jupiter.DefaultTimeZone;
38
39
40
41
42 class FastDatePrinterTest extends AbstractLangTest {
43
44 private enum Expected1806 {
45 India(INDIA, "+05", "+0530", "+05:30"), Greenwich(TimeZones.GMT, "Z", "Z", "Z"), NewYork(NEW_YORK, "-05", "-0500", "-05:00");
46
47 final TimeZone zone;
48
49 final String one;
50 final String two;
51 final String three;
52
53 Expected1806(final TimeZone zone, final String one, final String two, final String three) {
54 this.zone = zone;
55 this.one = one;
56 this.two = two;
57 this.three = three;
58 }
59 }
60
61 private static final String YYYY_MM_DD = "yyyy/MM/dd";
62 private static final TimeZone NEW_YORK = TimeZones.getTimeZone("America/New_York");
63 private static final TimeZone INDIA = TimeZones.getTimeZone("Asia/Calcutta");
64
65 private static final Locale SWEDEN = new Locale("sv", "SE");
66
67 private static Calendar initializeCalendar(final TimeZone tz) {
68 final Calendar cal = Calendar.getInstance(tz);
69 cal.set(Calendar.YEAR, 2001);
70 cal.set(Calendar.MONTH, 1);
71 cal.set(Calendar.DAY_OF_MONTH, 4);
72 cal.set(Calendar.HOUR_OF_DAY, 12);
73 cal.set(Calendar.MINUTE, 8);
74 cal.set(Calendar.SECOND, 56);
75 cal.set(Calendar.MILLISECOND, 235);
76 return cal;
77 }
78
79 private DatePrinter getDateInstance(final int dateStyle, final Locale locale) {
80 return getInstance(AbstractFormatCache.getPatternForStyle(Integer.valueOf(dateStyle), null, locale), TimeZone.getDefault(), Locale.getDefault());
81 }
82
83 DatePrinter getInstance(final String format) {
84 return getInstance(format, TimeZone.getDefault(), Locale.getDefault());
85 }
86
87 private DatePrinter getInstance(final String format, final Locale locale) {
88 return getInstance(format, TimeZone.getDefault(), locale);
89 }
90
91 private DatePrinter getInstance(final String format, final TimeZone timeZone) {
92 return getInstance(format, timeZone, Locale.getDefault());
93 }
94
95
96
97
98
99
100
101
102
103 protected DatePrinter getInstance(final String format, final TimeZone timeZone, final Locale locale) {
104 return new FastDatePrinter(format, timeZone, locale);
105 }
106
107 @Test
108 void test1806() {
109 for (final Expected1806 trial : Expected1806.values()) {
110 final Calendar cal = initializeCalendar(trial.zone);
111
112 DatePrinter printer = getInstance("X", trial.zone);
113 assertEquals(trial.one, printer.format(cal));
114
115 printer = getInstance("XX", trial.zone);
116 assertEquals(trial.two, printer.format(cal));
117
118 printer = getInstance("XXX", trial.zone);
119 assertEquals(trial.three, printer.format(cal));
120 }
121 }
122
123 @Test
124 void test1806Argument() {
125 assertIllegalArgumentException(() -> getInstance("XXXX"));
126 }
127
128 @Test
129 void testAppendableOptions() {
130 final DatePrinter format = getInstance("yyyy-MM-dd HH:mm:ss.SSS Z", TimeZones.GMT);
131 final Calendar calendar = Calendar.getInstance();
132 final StringBuilder sb = new StringBuilder();
133 final String expected = format.format(calendar, sb).toString();
134 sb.setLength(0);
135
136 final Date date = calendar.getTime();
137 assertEquals(expected, format.format(date, sb).toString());
138 sb.setLength(0);
139
140 final long epoch = date.getTime();
141 assertEquals(expected, format.format(epoch, sb).toString());
142 }
143
144 @Test
145 void testDayNumberOfWeek() {
146 final DatePrinter printer = getInstance("u");
147 final Calendar calendar = Calendar.getInstance();
148
149 calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
150 assertEquals("1", printer.format(calendar.getTime()));
151
152 calendar.set(Calendar.DAY_OF_WEEK, Calendar.SATURDAY);
153 assertEquals("6", printer.format(calendar.getTime()));
154
155 calendar.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
156 assertEquals("7", printer.format(calendar.getTime()));
157 }
158
159 @Test
160 void testEquals() {
161 final DatePrinter printer1 = getInstance(YYYY_MM_DD);
162 final DatePrinter printer2 = getInstance(YYYY_MM_DD);
163
164 assertEquals(printer1, printer2);
165 assertEquals(printer1.hashCode(), printer2.hashCode());
166
167 assertNotEquals(printer1, new Object());
168 }
169
170 @DefaultLocale(language = "en", country = "US")
171 @DefaultTimeZone("America/New_York")
172 @Test
173 void testFormat() {
174 final GregorianCalendar cal1 = new GregorianCalendar(2003, 0, 10, 15, 33, 20);
175 final GregorianCalendar cal2 = new GregorianCalendar(2003, 6, 10, 9, 0, 0);
176 final Date date1 = cal1.getTime();
177 final Date date2 = cal2.getTime();
178 final long millis1 = date1.getTime();
179 final long millis2 = date2.getTime();
180
181 DatePrinter fdf = getInstance("yyyy-MM-dd'T'HH:mm:ss");
182 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
183 assertEquals(sdf.format(date1), fdf.format(date1));
184 assertEquals("2003-01-10T15:33:20", fdf.format(date1));
185 assertEquals("2003-01-10T15:33:20", fdf.format(cal1));
186 assertEquals("2003-01-10T15:33:20", fdf.format(millis1));
187 assertEquals("2003-07-10T09:00:00", fdf.format(date2));
188 assertEquals("2003-07-10T09:00:00", fdf.format(cal2));
189 assertEquals("2003-07-10T09:00:00", fdf.format(millis2));
190
191 fdf = getInstance("Z");
192 assertEquals("-0500", fdf.format(date1));
193 assertEquals("-0500", fdf.format(cal1));
194 assertEquals("-0500", fdf.format(millis1));
195
196 assertEquals("-0400", fdf.format(date2));
197 assertEquals("-0400", fdf.format(cal2));
198 assertEquals("-0400", fdf.format(millis2));
199
200 fdf = getInstance("ZZ");
201 assertEquals("-05:00", fdf.format(date1));
202 assertEquals("-05:00", fdf.format(cal1));
203 assertEquals("-05:00", fdf.format(millis1));
204
205 assertEquals("-04:00", fdf.format(date2));
206 assertEquals("-04:00", fdf.format(cal2));
207 assertEquals("-04:00", fdf.format(millis2));
208
209 final String pattern = "GGGG GGG GG G yyyy yyy yy y MMMM MMM MM M LLLL LLL LL L"
210 + " dddd ddd dd d DDDD DDD DD D EEEE EEE EE E aaaa aaa aa a zzzz zzz zz z";
211 fdf = getInstance(pattern);
212 sdf = new SimpleDateFormat(pattern);
213
214 assertEquals(sdf.format(date1).replace("2003 03 03 03", "2003 2003 03 2003"), fdf.format(date1));
215 assertEquals(sdf.format(date2).replace("2003 03 03 03", "2003 2003 03 2003"), fdf.format(date2));
216 }
217
218 @Test
219 void testHourFormats() {
220 final Calendar calendar = Calendar.getInstance();
221 calendar.clear();
222 final DatePrinter printer = getInstance("K k H h");
223
224 calendar.set(Calendar.HOUR_OF_DAY, 0);
225 assertEquals("0 24 0 12", printer.format(calendar));
226
227 calendar.set(Calendar.HOUR_OF_DAY, 12);
228 assertEquals("0 12 12 12", printer.format(calendar));
229
230 calendar.set(Calendar.HOUR_OF_DAY, 23);
231 assertEquals("11 23 23 11", printer.format(calendar));
232 }
233
234 @Test
235 void testLang1103() {
236 final Calendar cal = Calendar.getInstance(SWEDEN);
237 cal.set(Calendar.DAY_OF_MONTH, 2);
238
239 assertEquals("2", getInstance("d", SWEDEN).format(cal));
240 assertEquals("02", getInstance("dd", SWEDEN).format(cal));
241 assertEquals("002", getInstance("ddd", SWEDEN).format(cal));
242 assertEquals("0002", getInstance("dddd", SWEDEN).format(cal));
243 assertEquals("00002", getInstance("ddddd", SWEDEN).format(cal));
244 }
245
246 @Test
247 void testLang303() {
248 final Calendar cal = Calendar.getInstance();
249 cal.set(2004, Calendar.DECEMBER, 31);
250
251 DatePrinter format = getInstance(YYYY_MM_DD);
252 final String output = format.format(cal);
253
254 format = SerializationUtils.deserialize(SerializationUtils.serialize((Serializable) format));
255 assertEquals(output, format.format(cal));
256 }
257
258 @Test
259 void testLang538() {
260
261
262 final GregorianCalendar cal = new GregorianCalendar(TimeZones.getTimeZone("GMT-8"));
263 cal.clear();
264 cal.set(2009, Calendar.OCTOBER, 16, 8, 42, 16);
265
266 final DatePrinter format = getInstance("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", TimeZones.GMT);
267 assertEquals("2009-10-16T16:42:16.000Z", format.format(cal.getTime()), "dateTime");
268 assertEquals("2009-10-16T16:42:16.000Z", format.format(cal), "dateTime");
269 }
270
271 @Test
272 void testLang645() {
273 final Locale locale = new Locale("sv", "SE");
274
275 final Calendar cal = Calendar.getInstance();
276 cal.set(2010, Calendar.JANUARY, 1, 12, 0, 0);
277 final Date d = cal.getTime();
278
279 final DatePrinter fdf = getInstance("EEEE', week 'ww", locale);
280
281 assertEquals("fredag, week 53", fdf.format(d));
282 }
283
284
285
286
287
288
289 @Test
290 void testLang916() {
291
292 final Calendar cal = Calendar.getInstance(TimeZones.getTimeZone("Europe/Paris"));
293 cal.clear();
294 cal.set(2009, 9, 16, 8, 42, 16);
295
296
297 {
298 final String value = FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mm:ss Z", TimeZones.getTimeZone("Europe/Paris")).format(cal);
299 assertEquals("2009-10-16T08:42:16 +0200", value, "calendar");
300 }
301 {
302 final String value = FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mm:ss Z", TimeZones.getTimeZone("Asia/Kolkata")).format(cal);
303 assertEquals("2009-10-16T12:12:16 +0530", value, "calendar");
304 }
305 {
306 final String value = FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mm:ss Z", TimeZones.getTimeZone("Europe/London")).format(cal);
307 assertEquals("2009-10-16T07:42:16 +0100", value, "calendar");
308 }
309 }
310
311 @Test
312 void testLocaleMatches() {
313 final DatePrinter printer = getInstance(YYYY_MM_DD, SWEDEN);
314 assertEquals(SWEDEN, printer.getLocale());
315 }
316
317
318
319
320 @Test
321 void testLowYearPadding() {
322 final Calendar cal = Calendar.getInstance();
323 final DatePrinter format = getInstance(YYYY_MM_DD);
324
325 cal.set(1, Calendar.JANUARY, 1);
326 assertEquals("0001/01/01", format.format(cal));
327 cal.set(10, Calendar.JANUARY, 1);
328 assertEquals("0010/01/01", format.format(cal));
329 cal.set(100, Calendar.JANUARY, 1);
330 assertEquals("0100/01/01", format.format(cal));
331 cal.set(999, Calendar.JANUARY, 1);
332 assertEquals("0999/01/01", format.format(cal));
333 }
334
335
336
337
338 @Test
339 void testMilleniumBug() {
340 final Calendar cal = Calendar.getInstance();
341 final DatePrinter format = getInstance("dd.MM.yyyy");
342
343 cal.set(1000, Calendar.JANUARY, 1);
344 assertEquals("01.01.1000", format.format(cal));
345 }
346
347 @Test
348 void testPatternMatches() {
349 final DatePrinter printer = getInstance(YYYY_MM_DD);
350 assertEquals(YYYY_MM_DD, printer.getPattern());
351 }
352
353
354
355
356 @Test
357 void testShortDateStyleWithLocales() {
358 final Locale usLocale = Locale.US;
359 final Locale swedishLocale = new Locale("sv", "SE");
360 final Calendar cal = Calendar.getInstance();
361 cal.set(2004, Calendar.FEBRUARY, 3);
362 DatePrinter fdf = getDateInstance(FastDateFormat.SHORT, usLocale);
363 assertEquals("2/3/04", fdf.format(cal));
364
365 fdf = getDateInstance(FastDateFormat.SHORT, swedishLocale);
366 assertEquals("2004-02-03", fdf.format(cal));
367
368 }
369
370
371
372
373 @Test
374 void testSimpleDate() {
375 final Calendar cal = Calendar.getInstance();
376 final DatePrinter format = getInstance(YYYY_MM_DD);
377
378 cal.set(2004, Calendar.DECEMBER, 31);
379 assertEquals("2004/12/31", format.format(cal));
380 cal.set(999, Calendar.DECEMBER, 31);
381 assertEquals("0999/12/31", format.format(cal));
382 cal.set(1, Calendar.MARCH, 2);
383 assertEquals("0001/03/02", format.format(cal));
384 }
385
386 @SuppressWarnings("deprecation")
387 @Test
388 void testStringBufferOptions() {
389 final DatePrinter format = getInstance("yyyy-MM-dd HH:mm:ss.SSS Z", TimeZones.GMT);
390 final Calendar calendar = Calendar.getInstance();
391 final StringBuffer sb = new StringBuffer();
392 final String expected = format.format(calendar, sb, new FieldPosition(0)).toString();
393 sb.setLength(0);
394 assertEquals(expected, format.format(calendar, sb).toString());
395 sb.setLength(0);
396
397 final Date date = calendar.getTime();
398 assertEquals(expected, format.format(date, sb, new FieldPosition(0)).toString());
399 sb.setLength(0);
400 assertEquals(expected, format.format(date, sb).toString());
401 sb.setLength(0);
402
403 final long epoch = date.getTime();
404 assertEquals(expected, format.format(epoch, sb, new FieldPosition(0)).toString());
405 sb.setLength(0);
406 assertEquals(expected, format.format(epoch, sb).toString());
407 }
408
409 @DefaultTimeZone("UTC")
410 @Test
411 void testTimeZoneAsZ() {
412 final Calendar c = Calendar.getInstance(FastTimeZone.getGmtTimeZone());
413 final FastDateFormat noColonFormat = FastDateFormat.getInstance("Z");
414 assertEquals("+0000", noColonFormat.format(c));
415
416 final FastDateFormat isoFormat = FastDateFormat.getInstance("ZZ");
417 assertEquals("Z", isoFormat.format(c));
418
419 final FastDateFormat colonFormat = FastDateFormat.getInstance("ZZZ");
420 assertEquals("+00:00", colonFormat.format(c));
421 }
422
423 @Test
424 void testTimeZoneMatches() {
425 final DatePrinter printer = getInstance(YYYY_MM_DD, NEW_YORK);
426 assertEquals(NEW_YORK, printer.getTimeZone());
427 }
428
429 @Test
430 void testToStringContainsName() {
431 final DatePrinter printer = getInstance(YYYY_MM_DD);
432 assertTrue(printer.toString().startsWith("FastDate"));
433 }
434
435 @DefaultLocale(language = "en", country = "US")
436 @DefaultTimeZone("America/New_York")
437 @Test
438 void testWeekYear() {
439 final GregorianCalendar cal = new GregorianCalendar(2020, 12, 31, 0, 0, 0);
440 final DatePrinter printer4Digits = getInstance("YYYY");
441 final DatePrinter printer4DigitsFallback = getInstance("YYY");
442 final DatePrinter printer2Digits = getInstance("YY");
443 final DatePrinter printer4DigitAnotherFallback = getInstance("Y");
444 assertEquals("2021", printer4Digits.format(cal));
445 assertEquals("2021", printer4DigitsFallback.format(cal));
446 assertEquals("2021", printer4DigitAnotherFallback.format(cal));
447 assertEquals("21", printer2Digits.format(cal));
448 }
449 }