2020import static org .junit .jupiter .api .Assertions .assertNull ;
2121
2222import java .text .SimpleDateFormat ;
23+ import java .time .ZoneId ;
24+ import java .time .format .DateTimeFormatter ;
25+ import java .time .temporal .TemporalAccessor ;
2326import java .util .Calendar ;
2427import java .util .Date ;
2528import java .util .TimeZone ;
2831import org .apache .logging .log4j .core .time .Instant ;
2932import org .apache .logging .log4j .core .time .MutableInstant ;
3033import org .apache .logging .log4j .core .util .Constants ;
31- import org .apache .logging .log4j .core .util .datetime .FixedDateFormat ;
32- import org .apache .logging .log4j .core .util .datetime .FixedDateFormat .FixedTimeZoneFormat ;
3334import org .apache .logging .log4j .util .Strings ;
3435import org .junit .jupiter .api .Test ;
3536
@@ -54,27 +55,13 @@ public long getTimeMillis() {
5455 }
5556 }
5657
57- /**
58- * SimpleTimePattern for DEFAULT.
59- */
60- private static final String DEFAULT_PATTERN = FixedDateFormat .FixedFormat .DEFAULT .getPattern ();
58+ private static final String DEFAULT_PATTERN = "yyyy-MM-dd HH:mm:ss,SSS" ;
6159
62- /**
63- * ISO8601 string literal.
64- */
65- private static final String ISO8601 = FixedDateFormat .FixedFormat .ISO8601 .name ();
60+ private static final String ISO8601 = "ISO8601" ;
6661
67- /**
68- * ISO8601_OFFSET_DATE_TIME_XX string literal.
69- */
70- private static final String ISO8601_OFFSET_DATE_TIME_HHMM =
71- FixedDateFormat .FixedFormat .ISO8601_OFFSET_DATE_TIME_HHMM .name ();
62+ private static final String ISO8601_OFFSET_DATE_TIME_HHMM = "ISO8601_OFFSET_DATE_TIME_HHMM" ;
7263
73- /**
74- * ISO8601_OFFSET_DATE_TIME_XXX string literal.
75- */
76- private static final String ISO8601_OFFSET_DATE_TIME_HHCMM =
77- FixedDateFormat .FixedFormat .ISO8601_OFFSET_DATE_TIME_HHCMM .name ();
64+ private static final String ISO8601_OFFSET_DATE_TIME_HHCMM = "ISO8601_OFFSET_DATE_TIME_HHCMM" ;
7865
7966 private static final String [] ISO8601_FORMAT_OPTIONS = {ISO8601 };
8067
@@ -91,14 +78,6 @@ private static Date date(final int year, final int month, final int date) {
9178 return cal .getTime ();
9279 }
9380
94- private String precisePattern (final String pattern , final int precision ) {
95- final String search = "SSS" ;
96- final int foundIndex = pattern .indexOf (search );
97- final String seconds = pattern .substring (0 , foundIndex );
98- final String remainder = pattern .substring (foundIndex + search .length ());
99- return seconds + "nnnnnnnnn" .substring (0 , precision ) + remainder ;
100- }
101-
10281 @ Test
10382 void testThreadLocalsConstant () {
10483 assertEquals (threadLocalsEnabled , Constants .ENABLE_THREADLOCALS );
@@ -109,6 +88,7 @@ public void testFormatDateStringBuilderDefaultPattern() {
10988 assertDatePattern (null , date (2001 , 1 , 1 ), "2001-02-01 14:15:16,123" );
11089 }
11190
91+ @ SuppressWarnings ("deprecation" )
11292 @ Test
11393 public void testFormatDateStringBuilderIso8601 () {
11494 final DatePatternConverter converter = DatePatternConverter .newInstance (ISO8601_FORMAT_OPTIONS );
@@ -121,19 +101,18 @@ public void testFormatDateStringBuilderIso8601() {
121101
122102 @ Test
123103 public void testFormatDateStringBuilderIso8601BasicWithPeriod () {
124- assertDatePattern (
125- FixedDateFormat .FixedFormat .ISO8601_BASIC_PERIOD .name (), date (2001 , 1 , 1 ), "20010201T141516.123" );
104+ assertDatePattern ("ISO8601_BASIC_PERIOD" , date (2001 , 1 , 1 ), "20010201T141516.123" );
126105 }
127106
128107 @ Test
129108 public void testFormatDateStringBuilderIso8601WithPeriod () {
130- assertDatePattern (
131- FixedDateFormat .FixedFormat .ISO8601_PERIOD .name (), date (2001 , 1 , 1 ), "2001-02-01T14:15:16.123" );
109+ assertDatePattern ("ISO8601_PERIOD" , date (2001 , 1 , 1 ), "2001-02-01T14:15:16.123" );
132110 }
133111
112+ @ SuppressWarnings ("deprecation" )
134113 @ Test
135114 public void testFormatDateStringBuilderIso8601WithPeriodMicroseconds () {
136- final String [] pattern = {FixedDateFormat . FixedFormat . ISO8601_PERIOD_MICROS . name () , "Z" };
115+ final String [] pattern = {" ISO8601_PERIOD_MICROS" , "Z" };
137116 final DatePatternConverter converter = DatePatternConverter .newInstance (pattern );
138117 final StringBuilder sb = new StringBuilder ();
139118 final MutableInstant instant = new MutableInstant ();
@@ -180,11 +159,12 @@ public void testFormatAmericanPatterns() {
180159 assertDatePattern ("US_MONTH_DAY_YEAR4_TIME" , date , "11/03/2011 14:15:16.123" );
181160 assertDatePattern ("US_MONTH_DAY_YEAR2_TIME" , date , "11/03/11 14:15:16.123" );
182161 assertDatePattern ("dd/MM/yyyy HH:mm:ss.SSS" , date , "11/03/2011 14:15:16.123" );
183- assertDatePattern ("dd/MM/yyyy HH:mm:ss.nnnnnn " , date , "11/03/2011 14:15:16.123000" );
162+ assertDatePattern ("dd/MM/yyyy HH:mm:ss.SSSSSS " , date , "11/03/2011 14:15:16.123000" );
184163 assertDatePattern ("dd/MM/yy HH:mm:ss.SSS" , date , "11/03/11 14:15:16.123" );
185- assertDatePattern ("dd/MM/yy HH:mm:ss.nnnnnn " , date , "11/03/11 14:15:16.123000" );
164+ assertDatePattern ("dd/MM/yy HH:mm:ss.SSSSSS " , date , "11/03/11 14:15:16.123000" );
186165 }
187166
167+ @ SuppressWarnings ("deprecation" )
188168 private static void assertDatePattern (final String format , final Date date , final String expected ) {
189169 final DatePatternConverter converter = DatePatternConverter .newInstance (new String [] {format });
190170 final StringBuilder sb = new StringBuilder ();
@@ -219,9 +199,9 @@ public void testFormatLogEventStringBuilderIso8601TimezoneOffsetHHCMM() {
219199 final StringBuilder sb = new StringBuilder ();
220200 converter .format (event , sb );
221201
222- final SimpleDateFormat sdf = new SimpleDateFormat (converter .getPattern ());
223- final String format = sdf . format ( new Date ( event . getTimeMillis ()));
224- final String expected = format . endsWith ( "Z" ) ? format . substring ( 0 , format . length () - 1 ) + "+00:00" : format ;
202+ final String expected = DateTimeFormatter . ofPattern (converter .getPattern ())
203+ . withZone ( ZoneId . systemDefault ())
204+ . format (( TemporalAccessor ) event . getInstant ()) ;
225205 assertEquals (expected , sb .toString ());
226206 }
227207
@@ -233,9 +213,9 @@ public void testFormatLogEventStringBuilderIso8601TimezoneOffsetHHMM() {
233213 final StringBuilder sb = new StringBuilder ();
234214 converter .format (event , sb );
235215
236- final SimpleDateFormat sdf = new SimpleDateFormat (converter .getPattern ());
237- final String format = sdf . format ( new Date ( event . getTimeMillis ()));
238- final String expected = format . endsWith ( "Z" ) ? format . substring ( 0 , format . length () - 1 ) + "+0000" : format ;
216+ final String expected = DateTimeFormatter . ofPattern (converter .getPattern ())
217+ . withZone ( ZoneId . systemDefault ())
218+ . format (( TemporalAccessor ) event . getInstant ()) ;
239219 assertEquals (expected , sb .toString ());
240220 }
241221
@@ -311,7 +291,7 @@ public void testGetPatternReturnsDefaultForEmptyOptionsArray() {
311291
312292 @ Test
313293 public void testGetPatternReturnsDefaultForInvalidPattern () {
314- final String [] invalid = {"ABC I am not a valid date pattern " };
294+ final String [] invalid = {"A single `V` is not allow by `DateTimeFormatter` and should cause an exception " };
315295 assertEquals (DEFAULT_PATTERN , DatePatternConverter .newInstance (invalid ).getPattern ());
316296 }
317297
@@ -344,126 +324,52 @@ public void testGetPatternReturnsNullForUnixMillis() {
344324 assertNull (DatePatternConverter .newInstance (options ).getPattern ());
345325 }
346326
347- @ Test
348- public void testInvalidLongPatternIgnoresExcessiveDigits () {
349- final StringBuilder preciseBuilder = new StringBuilder ();
350- final StringBuilder milliBuilder = new StringBuilder ();
351- final LogEvent event = new MyLogEvent ();
352-
353- for (final FixedDateFormat .FixedFormat format : FixedDateFormat .FixedFormat .values ()) {
354- final String pattern = format .getPattern ();
355- final String search = "SSS" ;
356- final int foundIndex = pattern .indexOf (search );
357- if (pattern .endsWith ("n" ) || pattern .matches (".+n+X*" ) || pattern .matches (".+n+Z*" )) {
358- // ignore patterns that already have precise time formats
359- // ignore patterns that do not use seconds.
360- continue ;
361- }
362- preciseBuilder .setLength (0 );
363- milliBuilder .setLength (0 );
364-
365- final DatePatternConverter preciseConverter ;
366- final String precisePattern ;
367- if (foundIndex < 0 ) {
368- precisePattern = pattern ;
369- } else {
370- final String subPattern = pattern .substring (0 , foundIndex );
371- final String remainder = pattern .substring (foundIndex + search .length ());
372- precisePattern = subPattern + "nnnnnnnnn" + "n" + remainder ; // nanos too long
373- }
374- preciseConverter = DatePatternConverter .newInstance (new String [] {precisePattern });
375- preciseConverter .format (event , preciseBuilder );
376-
377- final String [] milliOptions = {pattern };
378- DatePatternConverter .newInstance (milliOptions ).format (event , milliBuilder );
379- final FixedTimeZoneFormat timeZoneFormat = format .getFixedTimeZoneFormat ();
380- final int truncateLen = 3 + (timeZoneFormat != null ? timeZoneFormat .getLength () : 0 );
381- final String tz = timeZoneFormat != null
382- ? milliBuilder .substring (milliBuilder .length () - timeZoneFormat .getLength (), milliBuilder .length ())
383- : Strings .EMPTY ;
384- milliBuilder .setLength (milliBuilder .length () - truncateLen ); // truncate millis
385- if (foundIndex >= 0 ) {
386- milliBuilder .append ("987123456" );
387- }
388- final String expected = milliBuilder .append (tz ).toString ();
389-
390- assertEquals (
391- expected ,
392- preciseBuilder .toString (),
393- "format = " + format + ", pattern = " + pattern + ", precisePattern = " + precisePattern );
394- // System.out.println(preciseOptions[0] + ": " + precise);
395- }
396- }
397-
398327 @ Test
399328 public void testNewInstanceAllowsNullParameter () {
400329 DatePatternConverter .newInstance (null ); // no errors
401330 }
402331
403- // test with all formats from one 'n' (100s of millis) to 'nnnnnnnnn' (nanosecond precision)
404- @ Test
405- public void testPredefinedFormatWithAnyValidNanoPrecision () {
406- final StringBuilder preciseBuilder = new StringBuilder ();
407- final StringBuilder milliBuilder = new StringBuilder ();
408- final LogEvent event = new MyLogEvent ();
409-
410- for (final String timeZone : new String [] {"PST" , null }) { // Pacific Standard Time=UTC-8:00
411- for (final FixedDateFormat .FixedFormat format : FixedDateFormat .FixedFormat .values ()) {
412- for (int i = 1 ; i <= 9 ; i ++) {
413- final String pattern = format .getPattern ();
414- if (pattern .endsWith ("n" )
415- || pattern .matches (".+n+X*" )
416- || pattern .matches (".+n+Z*" )
417- || !pattern .contains ("SSS" )) {
418- // ignore patterns that already have precise time formats
419- // ignore patterns that do not use seconds.
420- continue ;
421- }
422- preciseBuilder .setLength (0 );
423- milliBuilder .setLength (0 );
424-
425- final String precisePattern = precisePattern (pattern , i );
426- final String [] preciseOptions = {precisePattern , timeZone };
427- final DatePatternConverter preciseConverter = DatePatternConverter .newInstance (preciseOptions );
428- preciseConverter .format (event , preciseBuilder );
429-
430- final String [] milliOptions = {pattern , timeZone };
431- DatePatternConverter .newInstance (milliOptions ).format (event , milliBuilder );
432- final FixedTimeZoneFormat timeZoneFormat = format .getFixedTimeZoneFormat ();
433- final int truncateLen = 3 + (timeZoneFormat != null ? timeZoneFormat .getLength () : 0 );
434- final String tz = timeZoneFormat != null
435- ? milliBuilder .substring (
436- milliBuilder .length () - timeZoneFormat .getLength (), milliBuilder .length ())
437- : Strings .EMPTY ;
438- milliBuilder .setLength (milliBuilder .length () - truncateLen ); // truncate millis
439- final String expected =
440- milliBuilder .append ("987123456" , 0 , i ).append (tz ).toString ();
441-
442- assertEquals (
443- expected ,
444- preciseBuilder .toString (),
445- "format = " + format + ", pattern = " + pattern + ", precisePattern = " + precisePattern );
446- // System.out.println(preciseOptions[0] + ": " + precise);
447- }
448- }
449- }
450- }
332+ private static final String [] PATTERN_NAMES = {
333+ "ABSOLUTE" ,
334+ "ABSOLUTE_MICROS" ,
335+ "ABSOLUTE_NANOS" ,
336+ "ABSOLUTE_PERIOD" ,
337+ "COMPACT" ,
338+ "DATE" ,
339+ "DATE_PERIOD" ,
340+ "DEFAULT" ,
341+ "DEFAULT_MICROS" ,
342+ "DEFAULT_NANOS" ,
343+ "DEFAULT_PERIOD" ,
344+ "ISO8601_BASIC" ,
345+ "ISO8601_BASIC_PERIOD" ,
346+ "ISO8601" ,
347+ "ISO8601_OFFSET_DATE_TIME_HH" ,
348+ "ISO8601_OFFSET_DATE_TIME_HHMM" ,
349+ "ISO8601_OFFSET_DATE_TIME_HHCMM" ,
350+ "ISO8601_PERIOD" ,
351+ "ISO8601_PERIOD_MICROS" ,
352+ "US_MONTH_DAY_YEAR2_TIME" ,
353+ "US_MONTH_DAY_YEAR4_TIME"
354+ };
451355
452356 @ Test
453357 public void testPredefinedFormatWithoutTimezone () {
454- for (final FixedDateFormat . FixedFormat format : FixedDateFormat . FixedFormat . values () ) {
455- final String [] options = {format . name () };
358+ for (final String patternName : PATTERN_NAMES ) {
359+ final String [] options = {patternName };
456360 final DatePatternConverter converter = DatePatternConverter .newInstance (options );
457- assertEquals (format .getPattern (), converter .getPattern ());
361+ final String expectedPattern = DatePatternConverter .decodeNamedPattern (patternName );
362+ assertEquals (expectedPattern , converter .getPattern ());
458363 }
459364 }
460365
461366 @ Test
462367 public void testPredefinedFormatWithTimezone () {
463- for (final FixedDateFormat . FixedFormat format : FixedDateFormat . FixedFormat . values () ) {
464- final String [] options = {format . name () , "PST" }; // Pacific Standard Time=UTC-8:00
368+ for (final String patternName : PATTERN_NAMES ) {
369+ final String [] options = {patternName , "PST" }; // Pacific Standard Time=UTC-8:00
465370 final DatePatternConverter converter = DatePatternConverter .newInstance (options );
466- assertEquals (format .getPattern (), converter .getPattern ());
371+ final String expectedPattern = DatePatternConverter .decodeNamedPattern (patternName );
372+ assertEquals (expectedPattern , converter .getPattern ());
467373 }
468374 }
469375}
0 commit comments