static String decodeNamedPattern()

in log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/DatePatternConverter.java [111:190]


    static String decodeNamedPattern(final String pattern) {

        // If legacy formatters are enabled, we need to produce output aimed for `FixedDateFormat` and `FastDateFormat`.
        // Otherwise, we need to produce output aimed for `DateTimeFormatter`.
        // In conclusion, we need to check if legacy formatters enabled and apply following transformations.
        //
        //                               | Microseconds | Nanoseconds | Time-zone
        // ------------------------------+--------------+-------------+-----------
        // Legacy formatter directive    | nnnnnn       | nnnnnnnnn   | X, XX, XXX
        // `DateTimeFormatter` directive | SSSSSS       | SSSSSSSSS   | x, xx, xxx
        //
        // Enabling legacy formatters mean that user requests the pattern to be formatted using deprecated
        // `FixedDateFormat` and `FastDateFormat`.
        // These two have, let's not say _bogus_, but an _interesting_ way of handling certain pattern directives:
        //
        // - They say they adhere to `SimpleDateFormat` specification, but use `n` directive.
        //   `n` is neither defined by `SimpleDateFormat`, nor `SimpleDateFormat` supports sub-millisecond precisions.
        //   `n` is probably manually introduced by Log4j to support sub-millisecond precisions.
        //
        // - `n` denotes nano-of-second for `DateTimeFormatter`.
        //   In Java 17, `n` and `N` (nano-of-day) always output nanosecond precision.
        //   This is independent of how many times they occur consequently.
        //   Yet legacy formatters use repeated `n` to denote sub-milliseconds precision of certain length.
        //   This doesn't work for `DateTimeFormatter`, which needs
        //
        //   - `SSSSSS` for 6-digit microsecond precision
        //   - `SSSSSSSSS` for 9-digit nanosecond precision
        //
        // - Legacy formatters use `X`, `XX,` and `XXX` to choose between `+00`, `+0000`, or `+00:00`.
        //   This is the correct behaviour for `SimpleDateFormat`.
        //   Though `X` in `DateTimeFormatter` produces `Z` for zero-offset.
        //   To avoid the `Z` output, one needs to use `x` with `DateTimeFormatter`.
        final boolean compat = InstantPatternFormatter.LEGACY_FORMATTERS_ENABLED;

        switch (pattern) {
            case "ABSOLUTE":
                return "HH:mm:ss,SSS";
            case "ABSOLUTE_MICROS":
                return "HH:mm:ss," + (compat ? "nnnnnn" : "SSSSSS");
            case "ABSOLUTE_NANOS":
                return "HH:mm:ss," + (compat ? "nnnnnnnnn" : "SSSSSSSSS");
            case "ABSOLUTE_PERIOD":
                return "HH:mm:ss.SSS";
            case "COMPACT":
                return "yyyyMMddHHmmssSSS";
            case "DATE":
                return "dd MMM yyyy HH:mm:ss,SSS";
            case "DATE_PERIOD":
                return "dd MMM yyyy HH:mm:ss.SSS";
            case "DEFAULT":
                return "yyyy-MM-dd HH:mm:ss,SSS";
            case "DEFAULT_MICROS":
                return "yyyy-MM-dd HH:mm:ss," + (compat ? "nnnnnn" : "SSSSSS");
            case "DEFAULT_NANOS":
                return "yyyy-MM-dd HH:mm:ss," + (compat ? "nnnnnnnnn" : "SSSSSSSSS");
            case "DEFAULT_PERIOD":
                return "yyyy-MM-dd HH:mm:ss.SSS";
            case "ISO8601_BASIC":
                return "yyyyMMdd'T'HHmmss,SSS";
            case "ISO8601_BASIC_PERIOD":
                return "yyyyMMdd'T'HHmmss.SSS";
            case "ISO8601":
                return "yyyy-MM-dd'T'HH:mm:ss,SSS";
            case "ISO8601_OFFSET_DATE_TIME_HH":
                return "yyyy-MM-dd'T'HH:mm:ss,SSS" + (compat ? "X" : "x");
            case "ISO8601_OFFSET_DATE_TIME_HHMM":
                return "yyyy-MM-dd'T'HH:mm:ss,SSS" + (compat ? "XX" : "xx");
            case "ISO8601_OFFSET_DATE_TIME_HHCMM":
                return "yyyy-MM-dd'T'HH:mm:ss,SSS" + (compat ? "XXX" : "xxx");
            case "ISO8601_PERIOD":
                return "yyyy-MM-dd'T'HH:mm:ss.SSS";
            case "ISO8601_PERIOD_MICROS":
                return "yyyy-MM-dd'T'HH:mm:ss." + (compat ? "nnnnnn" : "SSSSSS");
            case "US_MONTH_DAY_YEAR2_TIME":
                return "dd/MM/yy HH:mm:ss.SSS";
            case "US_MONTH_DAY_YEAR4_TIME":
                return "dd/MM/yyyy HH:mm:ss.SSS";
        }
        return pattern;
    }