I have a legacy web application with Java code compiled and running in Java 5, when trying to build a new environment to run the same code in Java 12 I came across a date formatting problem. I've tested this in Java 5, 7, 8, 9, 10, 11, 12 and the code behaviour changes when using Java 9 or above.
I don't have the option of changing the Java source code of the web application.
The problem is to do with using java.text.DateFormat and the parse(String) method.
This little test application shows the problem:
import java.util.*;
import java.text.*;
public class LocaleAndDateTester {
public LocaleAndDateTester() {
}
public static final void main(String[] argv) {
LocaleAndDateTester a = new LocaleAndDateTester();
a.go();
}
private void go() {
System.out.println("Locale country: " + Locale.getDefault().getDisplayCountry());
java.text.DateFormat df = java.text.DateFormat.getDateInstance();
String[] dateToTest = {"01-JAN-2020", "12-SEP-2019", "12/SEP/2019", "12/09/2019",
"September 12, 2019", "Sep 12, 2019", "12 Sep 2019",
"12 September 2019"};
System.out.println("\nTesting dates:");
for (int i = 0; i < dateToTest.length; i++) {
try {
Date date = df.parse(dateToTest[i]);
System.out.println(dateToTest[i] + " -> " + date);
} catch (ParseException e) {
System.out.println(e.toString());
}
}
}
}
I compiled the code in Java 5, and ran the same class on different versions.
Running this in Java 5 to 8, the output this this:
Locale country: United Kingdom
Testing dates:
01-JAN-2020 -> Wed Jan 01 00:00:00 GMT 2020
12-SEP-2019 -> Thu Sep 12 00:00:00 BST 2019
java.text.ParseException: Unparseable date: "12/SEP/2019"
java.text.ParseException: Unparseable date: "12/09/2019"
java.text.ParseException: Unparseable date: "September 12, 2019"
java.text.ParseException: Unparseable date: "Sep 12, 2019"
java.text.ParseException: Unparseable date: "12 Sep 2019"
java.text.ParseException: Unparseable date: "12 September 2019"
Running in Java 9 or above, the output is this:
Locale country: United Kingdom
Testing dates:
java.text.ParseException: Unparseable date: "01-JAN-2020"
java.text.ParseException: Unparseable date: "12-SEP-2019"
java.text.ParseException: Unparseable date: "12/SEP/2019"
java.text.ParseException: Unparseable date: "12/09/2019"
java.text.ParseException: Unparseable date: "September 12, 2019"
java.text.ParseException: Unparseable date: "Sep 12, 2019"
12 Sep 2019 -> Thu Sep 12 00:00:00 GMT 2019
12 September 2019 -> Thu Sep 12 00:00:00 GMT 2019
This change of default behaviour of the DateFormat parse method causes errors in my web application.
Has anyone seen this, and worked out how to get the default to remain consistent through different Java versions?
I wondered if it was to do with OS environment variables getting passed into Java System Properties. The closest I got to that causing a change was in changing the "user.country" Java property. But I couldn't find a setting that would give dates parsed from DD-MMM-YYYY format.
Remember - I cannot change java source code - I can only modify OS environment properties and Java System Properties.
SOLUTION
Provided through an answer below, which gives a related article.
I've tested this on Java 11 and 12, and it works. Add the following command-line option to the java command:
-Djava.locale.providers=COMPAT,CLDR
Running the test application in Java 11 or 12 with that command-line option will give the same output as running with Java 8 or lower, without the command-line option.