ADDITIONAL SYSTEM INFORMATION : With Java 1.8.0_292 and Java 11.0.11 on Linux this all works fine. With Java 17 it fails. A DESCRIPTION OF THE PROBLEM : In Java 8 and 11 formatting and parsing a date using the Locale.UK used the shortname "Sep" for September. With Java 17 this has changed to "Sept". Only September has been changed to 4 letters, all other months remain at the expected 3 letters. This change causes fatal parsing errors when trying to parse historical logging. Changing to a different Locale like Locale.US or Locale.ENGLISH is not an option as these do not follow the ISO standard about weekdays (i.e. the Monday/Sunday thing) which are fields I'm looking for in my code. I have not been able to find a locale that is "ENGLISH" and conforms to the ISO standards. Both Locale.US and Locale.ENGLISH do it the US way. Background: The tests in my project failed when trying to build it with Java 17 https://github.com/nielsbasjes/logparser/blob/master/httpdlog/httpdlog-parser/src/test/java/nl/basjes/parse/httpdlog/dissectors/TestTimeStampDissector.java#L158 REGRESSION : Last worked in version 11.0.14 STEPS TO FOLLOW TO REPRODUCE THE PROBLEM : Create a file September.java with the content below and then using Java 17 simply do: javac September.java && java September. EXPECTED VERSUS ACTUAL BEHAVIOR : EXPECTED - Specific lines from the output of the provided reproduction code: en_GB 01/Sep/2021:12:11:12 +0200 en_GB Test case: 30/sep/2016:00:00:06 +0000 : Passed: {InstantSeconds=1475193606, OffsetSeconds=0},ISO,Europe/Amsterdam resolved to 2016-09-30T00:00:06 ACTUAL - Specific lines from the output of the provided reproduction code: en_GB 01/Sept/2021:12:11:12 +0200 en_GB Test case: 30/sep/2016:00:00:06 +0000 : Failed: Text '30/sep/2016:00:00:06 +0000' could not be parsed at index 3 ---------- BEGIN SOURCE ---------- import java.time.Instant; import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatterBuilder; import java.time.temporal.WeekFields; import java.util.Arrays; import java.util.List; import java.util.Locale; public class September { public static void main( String[] args ) { show(Locale.UK); // The default Locale that follows the ISO-8601 WeekFields show(Locale.US); show(Locale.ENGLISH); } public static void show(Locale locale) { System.err.println("===============: With Locale " + locale.toString()); showWeekfields(locale); // The default parser to what we find in the Apache httpd Logfiles // [05/Sep/2010:11:27:50 +0200] String defaultApacheDateTimePattern = "dd/MMM/yyyy:HH:mm:ss ZZ"; DateTimeFormatter formatter = new DateTimeFormatterBuilder() .parseCaseInsensitive() .appendPattern(defaultApacheDateTimePattern) .toFormatter() .withLocale(locale) .withZone(ZoneId.of("Europe/Amsterdam")); List<String> printCases = Arrays.asList( "2021-01-01T10:11:12.00Z", "2021-02-01T10:11:12.00Z", "2021-03-01T10:11:12.00Z", "2021-04-01T10:11:12.00Z", "2021-05-01T10:11:12.00Z", "2021-06-01T10:11:12.00Z", "2021-07-01T10:11:12.00Z", "2021-08-01T10:11:12.00Z", "2021-09-01T10:11:12.00Z", "2021-10-01T10:11:12.00Z", "2021-11-01T10:11:12.00Z", "2021-12-01T10:11:12.00Z"); for (String testCase: printCases) { System.err.println(locale.toString() + " " + formatter.format(Instant.parse(testCase))); } String timestamp = "30/sep/2016:00:00:06 +0000"; System.err.print(locale + " Test case: " + timestamp + " : "); try { System.err.println("Passed: " + formatter.parse(timestamp)); } catch (Exception e) { System.err.println("Failed: " + e.getMessage()); } } public static void showWeekfields(Locale locale) { WeekFields localeWeekFields = WeekFields.of(locale); WeekFields isoWeekFields = WeekFields.ISO; if (localeWeekFields.getFirstDayOfWeek().equals(isoWeekFields.getFirstDayOfWeek())) { System.err.println(locale + " has ISO FirstDayOfWeek"); } else { System.err.println(locale + " DOES NOT HAVE ISO FirstDayOfWeek"); } if (localeWeekFields.getMinimalDaysInFirstWeek() == isoWeekFields.getMinimalDaysInFirstWeek()) { System.err.println(locale + " has ISO MinimalDaysInFirstWeek"); } else { System.err.println(locale + " DOES NOT HAVE ISO MinimalDaysInFirstWeek"); } } } ---------- END SOURCE ---------- CUSTOMER SUBMITTED WORKAROUND : The hack that seems to work in some specific cases is to catch the exception and using a regular expression replace "sep" with "sept" and then try again. FREQUENCY : always
|