|
16 | 16 | */ |
17 | 17 | package org.apache.logging.log4j.core.pattern; |
18 | 18 |
|
| 19 | +import static org.apache.logging.log4j.core.util.internal.instant.InstantPatternFormatter.LEGACY_FORMATTERS_ENABLED; |
| 20 | + |
19 | 21 | import org.apache.logging.log4j.core.util.internal.instant.InstantPatternFormatter; |
20 | 22 |
|
21 | | -// If legacy formatters are enabled, we need to produce output aimed for `FixedDateFormat` and `FastDateFormat`. |
22 | | -// Otherwise, we need to produce output aimed for `DateTimeFormatter`. |
23 | | -// In conclusion, we need to check if legacy formatters enabled and apply following transformations. |
24 | | -// |
25 | | -// | Microseconds | Nanoseconds | Time-zone |
26 | | -// ------------------------------+--------------+-------------+----------- |
27 | | -// Legacy formatter directive | nnnnnn | nnnnnnnnn | X, XX, XXX |
28 | | -// `DateTimeFormatter` directive | SSSSSS | SSSSSSSSS | x, xx, xxx |
29 | | -// |
30 | | -// Enabling legacy formatters mean that user requests the pattern to be formatted using deprecated |
31 | | -// `FixedDateFormat` and `FastDateFormat`. |
32 | | -// These two have, let's not say _bogus_, but an _interesting_ way of handling certain pattern directives: |
33 | | -// |
34 | | -// - They say they adhere to `SimpleDateFormat` specification, but use `n` directive. |
35 | | -// `n` is neither defined by `SimpleDateFormat`, nor `SimpleDateFormat` supports sub-millisecond precisions. |
36 | | -// `n` is probably manually introduced by Log4j to support sub-millisecond precisions. |
37 | | -// |
38 | | -// - `n` denotes nano-of-second for `DateTimeFormatter`. |
39 | | -// In Java 17, `n` and `N` (nano-of-day) always output nanosecond precision. |
40 | | -// This is independent of how many times they occur consequently. |
41 | | -// Yet legacy formatters use repeated `n` to denote sub-milliseconds precision of certain length. |
42 | | -// This doesn't work for `DateTimeFormatter`, which needs |
43 | | -// |
44 | | -// - `SSSSSS` for 6-digit microsecond precision |
45 | | -// - `SSSSSSSSS` for 9-digit nanosecond precision |
46 | | -// |
47 | | -// - Legacy formatters use `X`, `XX,` and `XXX` to choose between `+00`, `+0000`, or `+00:00`. |
48 | | -// This is the correct behaviour for `SimpleDateFormat`. |
49 | | -// Though `X` in `DateTimeFormatter` produces `Z` for zero-offset. |
50 | | -// To avoid the `Z` output, one needs to use `x` with `DateTimeFormatter`. |
51 | 23 | /** |
52 | | - * Represents named date/time patterns for formatting log timestamps. |
53 | | - * Provides patterns for legacy and modern formatters based on configuration. |
| 24 | + * Represents named date & time patterns for formatting log timestamps. |
| 25 | + * |
| 26 | + * @see InstantPatternFormatter#LEGACY_FORMATTERS_ENABLED |
| 27 | + * @see DatePatternConverter |
| 28 | + * @since 2.26.0 |
54 | 29 | */ |
55 | | -@SuppressWarnings("SpellCheckingInspection") |
56 | 30 | public enum NamedDatePattern { |
| 31 | + |
| 32 | + // If legacy formatters are enabled, we need to produce output aimed for `FixedDateFormat` and `FastDateFormat`. |
| 33 | + // Otherwise, we need to produce output aimed for `DateTimeFormatter`. |
| 34 | + // In conclusion, we need to check if legacy formatters enabled and apply following transformations. |
| 35 | + // |
| 36 | + // | Microseconds | Nanoseconds | Time-zone |
| 37 | + // ------------------------------+--------------+-------------+----------- |
| 38 | + // Legacy formatter directive | nnnnnn | nnnnnnnnn | X, XX, XXX |
| 39 | + // `DateTimeFormatter` directive | SSSSSS | SSSSSSSSS | x, xx, xxx |
| 40 | + // |
| 41 | + // Enabling legacy formatters mean that user requests the pattern to be formatted using deprecated |
| 42 | + // `FixedDateFormat` and `FastDateFormat`. |
| 43 | + // These two have, let's not say _bogus_, but an _interesting_ way of handling certain pattern directives: |
| 44 | + // |
| 45 | + // - They say they adhere to `SimpleDateFormat` specification, but use `n` directive. |
| 46 | + // `n` is neither defined by `SimpleDateFormat`, nor `SimpleDateFormat` supports sub-millisecond precisions. |
| 47 | + // `n` is probably manually introduced by Log4j to support sub-millisecond precisions. |
| 48 | + // |
| 49 | + // - `n` denotes nano-of-second for `DateTimeFormatter`. |
| 50 | + // In Java 17, `n` and `N` (nano-of-day) always output nanosecond precision. |
| 51 | + // This is independent of how many times they occur consequently. |
| 52 | + // Yet legacy formatters use repeated `n` to denote sub-milliseconds precision of certain length. |
| 53 | + // This doesn't work for `DateTimeFormatter`, which needs |
| 54 | + // |
| 55 | + // - `SSSSSS` for 6-digit microsecond precision |
| 56 | + // - `SSSSSSSSS` for 9-digit nanosecond precision |
| 57 | + // |
| 58 | + // - Legacy formatters use `X`, `XX,` and `XXX` to choose between `+00`, `+0000`, or `+00:00`. |
| 59 | + // This is the correct behaviour for `SimpleDateFormat`. |
| 60 | + // Though `X` in `DateTimeFormatter` produces `Z` for zero-offset. |
| 61 | + // To avoid the `Z` output, one needs to use `x` with `DateTimeFormatter`. |
| 62 | + |
57 | 63 | ABSOLUTE("HH:mm:ss,SSS"), |
58 | | - ABSOLUTE_MICROS("HH:mm:ss," + (InstantPatternFormatter.LEGACY_FORMATTERS_ENABLED ? "nnnnnn" : "SSSSSS")), |
59 | | - ABSOLUTE_NANOS("HH:mm:ss," + (InstantPatternFormatter.LEGACY_FORMATTERS_ENABLED ? "nnnnnnnnn" : "SSSSSSSSS")), |
| 64 | + |
| 65 | + ABSOLUTE_MICROS("HH:mm:ss," + (LEGACY_FORMATTERS_ENABLED ? "nnnnnn" : "SSSSSS")), |
| 66 | + |
| 67 | + ABSOLUTE_NANOS("HH:mm:ss," + (LEGACY_FORMATTERS_ENABLED ? "nnnnnnnnn" : "SSSSSSSSS")), |
| 68 | + |
60 | 69 | ABSOLUTE_PERIOD("HH:mm:ss.SSS"), |
| 70 | + |
61 | 71 | COMPACT("yyyyMMddHHmmssSSS"), |
| 72 | + |
62 | 73 | DATE("dd MMM yyyy HH:mm:ss,SSS"), |
| 74 | + |
63 | 75 | DATE_PERIOD("dd MMM yyyy HH:mm:ss.SSS"), |
| 76 | + |
64 | 77 | DEFAULT("yyyy-MM-dd HH:mm:ss,SSS"), |
65 | | - DEFAULT_MICROS("yyyy-MM-dd HH:mm:ss," + (InstantPatternFormatter.LEGACY_FORMATTERS_ENABLED ? "nnnnnn" : "SSSSSS")), |
66 | | - DEFAULT_NANOS( |
67 | | - "yyyy-MM-dd HH:mm:ss," + (InstantPatternFormatter.LEGACY_FORMATTERS_ENABLED ? "nnnnnnnnn" : "SSSSSSSSS")), |
| 78 | + |
| 79 | + DEFAULT_MICROS("yyyy-MM-dd HH:mm:ss," + (LEGACY_FORMATTERS_ENABLED ? "nnnnnn" : "SSSSSS")), |
| 80 | + |
| 81 | + DEFAULT_NANOS("yyyy-MM-dd HH:mm:ss," + (LEGACY_FORMATTERS_ENABLED ? "nnnnnnnnn" : "SSSSSSSSS")), |
| 82 | + |
68 | 83 | DEFAULT_PERIOD("yyyy-MM-dd HH:mm:ss.SSS"), |
| 84 | + |
69 | 85 | ISO8601_BASIC("yyyyMMdd'T'HHmmss,SSS"), |
| 86 | + |
70 | 87 | ISO8601_BASIC_PERIOD("yyyyMMdd'T'HHmmss.SSS"), |
| 88 | + |
71 | 89 | ISO8601("yyyy-MM-dd'T'HH:mm:ss,SSS"), |
72 | | - ISO8601_OFFSET_DATE_TIME_HH( |
73 | | - "yyyy-MM-dd'T'HH:mm:ss,SSS" + (InstantPatternFormatter.LEGACY_FORMATTERS_ENABLED ? "X" : "x")), |
74 | | - ISO8601_OFFSET_DATE_TIME_HHMM( |
75 | | - "yyyy-MM-dd'T'HH:mm:ss,SSS" + (InstantPatternFormatter.LEGACY_FORMATTERS_ENABLED ? "XX" : "xx")), |
76 | | - ISO8601_OFFSET_DATE_TIME_HHCMM( |
77 | | - "yyyy-MM-dd'T'HH:mm:ss,SSS" + (InstantPatternFormatter.LEGACY_FORMATTERS_ENABLED ? "XXX" : "xxx")), |
| 90 | + |
| 91 | + ISO8601_OFFSET_DATE_TIME_HH("yyyy-MM-dd'T'HH:mm:ss,SSS" + (LEGACY_FORMATTERS_ENABLED ? "X" : "x")), |
| 92 | + |
| 93 | + ISO8601_OFFSET_DATE_TIME_HHMM("yyyy-MM-dd'T'HH:mm:ss,SSS" + (LEGACY_FORMATTERS_ENABLED ? "XX" : "xx")), |
| 94 | + |
| 95 | + ISO8601_OFFSET_DATE_TIME_HHCMM("yyyy-MM-dd'T'HH:mm:ss,SSS" + (LEGACY_FORMATTERS_ENABLED ? "XXX" : "xxx")), |
| 96 | + |
78 | 97 | ISO8601_PERIOD("yyyy-MM-dd'T'HH:mm:ss.SSS"), |
79 | | - ISO8601_PERIOD_MICROS( |
80 | | - "yyyy-MM-dd'T'HH:mm:ss." + (InstantPatternFormatter.LEGACY_FORMATTERS_ENABLED ? "nnnnnn" : "SSSSSS")), |
| 98 | + |
| 99 | + ISO8601_PERIOD_MICROS("yyyy-MM-dd'T'HH:mm:ss." + (LEGACY_FORMATTERS_ENABLED ? "nnnnnn" : "SSSSSS")), |
| 100 | + |
81 | 101 | US_MONTH_DAY_YEAR2_TIME("dd/MM/yy HH:mm:ss.SSS"), |
| 102 | + |
82 | 103 | US_MONTH_DAY_YEAR4_TIME("dd/MM/yyyy HH:mm:ss.SSS"); |
| 104 | + |
83 | 105 | private final String pattern; |
84 | 106 |
|
85 | 107 | NamedDatePattern(String pattern) { |
|
0 commit comments