This is an automated email from the ASF dual-hosted git repository.

ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-lang.git

commit 7995aad79fab336a4534a5290fdd760df7f55dde
Author: Gary Gregory <[email protected]>
AuthorDate: Thu Oct 22 14:47:45 2020 -0400

    Split out tests for a Java 15 bug.
    
    These tests fail on Java 15 due to a bug which was only fixed for Java
    16.
    See https://bugs.openjdk.java.net/browse/JDK-8248434
    See https://bugs.openjdk.java.net/browse/JDK-8248655
---
 pom.xml                                            |  20 +
 .../apache/commons/lang3/function/TriFunction.java |  65 ++++
 .../lang3/time/FastDateFormat_ParserTest.java      |  33 --
 .../commons/lang3/time/FastDateParserTest.java     | 422 +++++++++------------
 .../lang3/time/Java15BugFastDateParserTest.java    | 156 ++++++++
 5 files changed, 429 insertions(+), 267 deletions(-)

diff --git a/pom.xml b/pom.xml
index 0aad6a3..83f70ad 100644
--- a/pom.xml
+++ b/pom.xml
@@ -941,6 +941,26 @@
         <jacoco.skip>true</jacoco.skip>
       </properties>
     </profile>
+    <profile>
+      <id>java15</id>
+      <activation>
+        <!-- This is ONLY activated for Java 15 -->
+        <jdk>15</jdk>
+      </activation>
+      <build>
+        <plugins>
+          <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-surefire-plugin</artifactId>
+            <configuration>
+              <excludes>
+                
<exclude>org/apache/commons/lang3/time/Java15BugFastDateParserTest.java</exclude>
               
+              </excludes>
+            </configuration>
+          </plugin>        
+        </plugins>
+      </build>
+    </profile>
 
     <profile>
       <id>benchmark</id>
diff --git a/src/main/java/org/apache/commons/lang3/function/TriFunction.java 
b/src/main/java/org/apache/commons/lang3/function/TriFunction.java
new file mode 100644
index 0000000..653013a
--- /dev/null
+++ b/src/main/java/org/apache/commons/lang3/function/TriFunction.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.lang3.function;
+
+import java.util.Objects;
+import java.util.function.Function;
+
+/**
+ * Represents a function that accepts three arguments and produces a result. 
This is the three-arity specialization of
+ * {@link Function}.
+ *
+ * <p>
+ * This is a <a href="package-summary.html">functional interface</a> whose 
functional method is
+ * {@link #apply(Object, Object, Object)}.
+ *
+ * @param <T> the type of the first argument to the function
+ * @param <U> the type of the second argument to the function
+ * @param <V> the type of the third argument to the function
+ * @param <R> the type of the result of the function
+ *
+ * @see Function
+ * @since 3.12.0
+ */
+@FunctionalInterface
+public interface TriFunction<T, U, V, R> {
+
+    /**
+     * Applies this function to the given arguments.
+     *
+     * @param t the first function argument
+     * @param u the second function argument
+     * @param v the third function argument
+     * @return the function result
+     */
+    R apply(T t, U u, V v);
+
+    /**
+     * Returns a composed function that first applies this function to its 
input, and then applies the {@code after}
+     * function to the result. If evaluation of either function throws an 
exception, it is relayed to the caller of the
+     * composed function.
+     *
+     * @param <W> the type of output of the {@code after} function, and of the 
composed function
+     * @param after the function to apply after this function is applied
+     * @return a composed function that first applies this function and then 
applies the {@code after} function
+     * @throws NullPointerException if after is null
+     */
+    default <W> TriFunction<T, U, V, W> andThen(Function<? super R, ? extends 
W> after) {
+        Objects.requireNonNull(after);
+        return (T t, U u, V v) -> after.apply(apply(t, u, v));
+    }
+}
diff --git 
a/src/test/java/org/apache/commons/lang3/time/FastDateFormat_ParserTest.java 
b/src/test/java/org/apache/commons/lang3/time/FastDateFormat_ParserTest.java
deleted file mode 100644
index bdbff2f..0000000
--- a/src/test/java/org/apache/commons/lang3/time/FastDateFormat_ParserTest.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.commons.lang3.time;
-
-import java.util.Locale;
-import java.util.TimeZone;
-
-/**
- * Unit tests for the parse methods of FastDateFormat
- *
- * @since 3.2
- */
-public class FastDateFormat_ParserTest extends FastDateParserTest {
-
-    @Override
-    protected DateParser getInstance(final String format, final TimeZone 
timeZone, final Locale locale) {
-        return FastDateFormat.getInstance(format, timeZone, locale);
-    }
-}
diff --git 
a/src/test/java/org/apache/commons/lang3/time/FastDateParserTest.java 
b/src/test/java/org/apache/commons/lang3/time/FastDateParserTest.java
index 817de7b..0fbce4a 100644
--- a/src/test/java/org/apache/commons/lang3/time/FastDateParserTest.java
+++ b/src/test/java/org/apache/commons/lang3/time/FastDateParserTest.java
@@ -34,10 +34,15 @@ import java.util.HashMap;
 import java.util.Locale;
 import java.util.Map;
 import java.util.TimeZone;
+import java.util.stream.Stream;
 
 import org.apache.commons.lang3.LocaleUtils;
 import org.apache.commons.lang3.SerializationUtils;
+import org.apache.commons.lang3.function.TriFunction;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
 
 /**
  * Unit tests {@link org.apache.commons.lang3.time.FastDateParser}.
@@ -45,9 +50,9 @@ import org.junit.jupiter.api.Test;
  * @since 3.2
  */
 public class FastDateParserTest {
+
     private enum Expected1806 {
-        India(INDIA, "+05", "+0530", "+05:30", true),
-        Greenwich(GMT, "Z", "Z", "Z", false),
+        India(INDIA, "+05", "+0530", "+05:30", true), Greenwich(GMT, "Z", "Z", 
"Z", false),
         NewYork(NEW_YORK, "-05", "-0500", "-05:00", false);
 
         final TimeZone zone;
@@ -56,33 +61,48 @@ public class FastDateParserTest {
         final String two;
         final String three;
         final long offset;
-        Expected1806(final TimeZone zone, final String one, final String two, 
final String three, final boolean hasHalfHourOffset) {
+
+        Expected1806(final TimeZone zone, final String one, final String two, 
final String three,
+            final boolean hasHalfHourOffset) {
             this.zone = zone;
             this.one = one;
             this.two = two;
             this.three = three;
-            this.offset = hasHalfHourOffset ?30*60*1000 :0;
+            this.offset = hasHalfHourOffset ? 30 * 60 * 1000 : 0;
         }
     }
-    private static final String SHORT_FORMAT_NOERA = "y/M/d/h/a/m/s/E";
-    private static final String LONG_FORMAT_NOERA = 
"yyyy/MMMM/dddd/hhhh/mmmm/ss/aaaa/EEEE";
-    private static final String SHORT_FORMAT = "G/" + SHORT_FORMAT_NOERA;
 
-    private static final String LONG_FORMAT = "GGGG/" + LONG_FORMAT_NOERA;
+    static final String DATE_PARSER_PARAMETERS = "dateParserParameters";
+
+    static final String SHORT_FORMAT_NOERA = "y/M/d/h/a/m/s/E";
+
+    static final String LONG_FORMAT_NOERA = 
"yyyy/MMMM/dddd/hhhh/mmmm/ss/aaaa/EEEE";
+    static final String SHORT_FORMAT = "G/" + SHORT_FORMAT_NOERA;
+    static final String LONG_FORMAT = "GGGG/" + LONG_FORMAT_NOERA;
+
     private static final String yMdHmsSZ = "yyyy-MM-dd'T'HH:mm:ss.SSS Z";
     private static final String DMY_DOT = "dd.MM.yyyy";
     private static final String YMD_SLASH = "yyyy/MM/dd";
     private static final String MDY_DASH = "MM-DD-yyyy";
-
     private static final String MDY_SLASH = "MM/DD/yyyy";
+
     private static final TimeZone REYKJAVIK = 
TimeZone.getTimeZone("Atlantic/Reykjavik");
     private static final TimeZone NEW_YORK = 
TimeZone.getTimeZone("America/New_York");
-    private static final TimeZone GMT = TimeZone.getTimeZone("GMT");
-
+    static final TimeZone GMT = TimeZone.getTimeZone("GMT");
     private static final TimeZone INDIA = 
TimeZone.getTimeZone("Asia/Calcutta");
 
     private static final Locale SWEDEN = new Locale("sv", "SE");
 
+    static Stream<Arguments> dateParserParameters() {
+        return Stream.of(
+        // @formatter:off
+            Arguments.of((TriFunction<String, TimeZone, Locale, DateParser>) 
(format, timeZone, locale)
+                -> new FastDateParser(format, timeZone, locale, null)),
+            Arguments.of((TriFunction<String, TimeZone, Locale, DateParser>) 
FastDateFormat::getInstance)
+        // @formatter:on
+        );
+    }
+
     private static Calendar initializeCalendar(final TimeZone tz) {
         final Calendar cal = Calendar.getInstance(tz);
         cal.set(Calendar.YEAR, 2001);
@@ -95,25 +115,30 @@ public class FastDateParserTest {
         return cal;
     }
 
-    private void checkParse(final Locale locale, final Calendar cal, final 
SimpleDateFormat sdf, final DateParser fdf) throws ParseException {
-        final String formattedDate= sdf.format(cal.getTime());
+    private final TriFunction<String, TimeZone, Locale, DateParser> 
dateParserProvider = (format, timeZone,
+        locale) -> new FastDateParser(format, timeZone, locale, null);
+
+    static void checkParse(final Locale locale, final Calendar cal, final 
SimpleDateFormat sdf, final DateParser fdf) {
+        final String formattedDate = sdf.format(cal.getTime());
         checkParse(locale, sdf, fdf, formattedDate);
         checkParse(locale, sdf, fdf, formattedDate.toLowerCase(locale));
         checkParse(locale, sdf, fdf, formattedDate.toUpperCase(locale));
     }
 
-    private void checkParse(final Locale locale, final SimpleDateFormat sdf, 
final DateParser fdf, final String formattedDate) throws ParseException {
+    static void checkParse(final Locale locale, final SimpleDateFormat sdf, 
final DateParser fdf,
+        final String formattedDate) {
         try {
             final Date expectedTime = sdf.parse(formattedDate);
             final Date actualTime = fdf.parse(formattedDate);
             assertEquals(expectedTime, actualTime, "locale : " + locale + " 
formattedDate : " + formattedDate + "\n");
-        } catch (Exception e) {
+        } catch (final Exception e) {
             fail("locale : " + locale + " formattedDate : " + formattedDate + 
" error : " + e + "\n", e);
         }
     }
 
     private DateParser getDateInstance(final int dateStyle, final Locale 
locale) {
-        return 
getInstance(FormatCache.getPatternForStyle(Integer.valueOf(dateStyle), null, 
locale), TimeZone.getDefault(), Locale.getDefault());
+        return getInstance(null, 
FormatCache.getPatternForStyle(Integer.valueOf(dateStyle), null, locale),
+            TimeZone.getDefault(), Locale.getDefault());
     }
 
     private Calendar getEraStart(int year, final TimeZone zone, final Locale 
locale) {
@@ -124,91 +149,68 @@ public class FastDateParserTest {
         if (locale.equals(FastDateParser.JAPANESE_IMPERIAL)) {
             if (year < 1868) {
                 cal.set(Calendar.ERA, 0);
-                cal.set(Calendar.YEAR, 1868-year);
+                cal.set(Calendar.YEAR, 1868 - year);
             }
         } else {
             if (year < 0) {
                 cal.set(Calendar.ERA, GregorianCalendar.BC);
-                year= -year;
+                year = -year;
             }
-            cal.set(Calendar.YEAR, year/100 * 100);
+            cal.set(Calendar.YEAR, year / 100 * 100);
         }
         return cal;
     }
 
     DateParser getInstance(final String format) {
-        return getInstance(format, TimeZone.getDefault(), Locale.getDefault());
+        return getInstance(null, format, TimeZone.getDefault(), 
Locale.getDefault());
     }
 
-    private DateParser getInstance(final String format, final Locale locale) {
-        return getInstance(format, TimeZone.getDefault(), locale);
+    DateParser getInstance(final String format, final Locale locale) {
+        return getInstance(null, format, TimeZone.getDefault(), locale);
     }
 
     private DateParser getInstance(final String format, final TimeZone 
timeZone) {
-        return getInstance(format, timeZone, Locale.getDefault());
+        return getInstance(null, format, timeZone, Locale.getDefault());
     }
 
     /**
      * Override this method in derived tests to change the construction of 
instances
      *
+     * @param dpProvider TODO
      * @param format the format string to use
      * @param timeZone the time zone to use
      * @param locale the locale to use
      *
      * @return the DateParser instance to use for testing
      */
-    protected DateParser getInstance(final String format, final TimeZone 
timeZone, final Locale locale) {
-        return new FastDateParser(format, timeZone, locale, null);
-    }
-
-    @Test
-    public void java15BuggyLocaleTest() throws ParseException {
-        final String buggyLocaleName = "ff_LR_#Adlm";
-        Locale buggyLocale = null;
-        for (final Locale locale : Locale.getAvailableLocales()) {
-            if (buggyLocaleName.equals(locale.toString())) {
-                buggyLocale = locale;
-                break;
-            }
-        }
-        if (buggyLocale == null) {
-            return;
-        }
-        testSingleLocale(buggyLocale);
-    }
-
-    @Test
-    public void java15BuggyLocaleTestAll() throws ParseException {
-        for (final Locale locale : Locale.getAvailableLocales()) {
-            testSingleLocale(locale);
-        }
-    }
-
-    @Test
-    public void test_Equality_Hash() {
-        final DateParser[] parsers= {
-            getInstance(yMdHmsSZ, NEW_YORK, Locale.US),
-            getInstance(DMY_DOT, NEW_YORK, Locale.US),
-            getInstance(YMD_SLASH, NEW_YORK, Locale.US),
-            getInstance(MDY_DASH, NEW_YORK, Locale.US),
-            getInstance(MDY_SLASH, NEW_YORK, Locale.US),
-            getInstance(MDY_SLASH, REYKJAVIK, Locale.US),
-            getInstance(MDY_SLASH, REYKJAVIK, SWEDEN)
-        };
-
-        final Map<DateParser, Integer> map= new HashMap<>();
-        int i= 0;
-        for (final DateParser parser:parsers) {
+    protected DateParser getInstance(final TriFunction<String, TimeZone, 
Locale, DateParser> dpProvider,
+        final String format, final TimeZone timeZone, final Locale locale) {
+        return (dpProvider == null ? this.dateParserProvider : 
dpProvider).apply(format, timeZone, locale);
+    }
+
+    @ParameterizedTest
+    @MethodSource(DATE_PARSER_PARAMETERS)
+    public void test_Equality_Hash(final TriFunction<String, TimeZone, Locale, 
DateParser> dpProvider) {
+        final DateParser[] parsers = {getInstance(dpProvider, yMdHmsSZ, 
NEW_YORK, Locale.US),
+            getInstance(dpProvider, DMY_DOT, NEW_YORK, Locale.US),
+            getInstance(dpProvider, YMD_SLASH, NEW_YORK, Locale.US),
+            getInstance(dpProvider, MDY_DASH, NEW_YORK, Locale.US),
+            getInstance(dpProvider, MDY_SLASH, NEW_YORK, Locale.US),
+            getInstance(dpProvider, MDY_SLASH, REYKJAVIK, Locale.US),
+            getInstance(dpProvider, MDY_SLASH, REYKJAVIK, SWEDEN)};
+
+        final Map<DateParser, Integer> map = new HashMap<>();
+        int i = 0;
+        for (final DateParser parser : parsers) {
             map.put(parser, Integer.valueOf(i++));
         }
 
-        i= 0;
-        for (final DateParser parser:parsers) {
+        i = 0;
+        for (final DateParser parser : parsers) {
             assertEquals(i++, map.get(parser).intValue());
         }
     }
 
-
     @Test
     public void test1806() throws ParseException {
         final String formatStub = "yyyy-MM-dd'T'HH:mm:ss.SSS";
@@ -217,16 +219,17 @@ public class FastDateParserTest {
         for (final Expected1806 trial : Expected1806.values()) {
             final Calendar cal = initializeCalendar(trial.zone);
 
-            final String message = trial.zone.getDisplayName()+";";
+            final String message = trial.zone.getDisplayName() + ";";
 
-            DateParser parser = getInstance(formatStub+"X", trial.zone);
-            assertEquals(cal.getTime().getTime(), 
parser.parse(dateStub+trial.one).getTime()-trial.offset, message+trial.one);
+            DateParser parser = getInstance(formatStub + "X", trial.zone);
+            assertEquals(cal.getTime().getTime(), parser.parse(dateStub + 
trial.one).getTime() - trial.offset,
+                message + trial.one);
 
-            parser = getInstance(formatStub+"XX", trial.zone);
-            assertEquals(cal.getTime(), parser.parse(dateStub+trial.two), 
message+trial.two);
+            parser = getInstance(formatStub + "XX", trial.zone);
+            assertEquals(cal.getTime(), parser.parse(dateStub + trial.two), 
message + trial.two);
 
-            parser = getInstance(formatStub+"XXX", trial.zone);
-            assertEquals(cal.getTime(), parser.parse(dateStub+trial.three), 
message+trial.three);
+            parser = getInstance(formatStub + "XXX", trial.zone);
+            assertEquals(cal.getTime(), parser.parse(dateStub + trial.three), 
message + trial.three);
         }
     }
 
@@ -235,15 +238,16 @@ public class FastDateParserTest {
         assertThrows(IllegalArgumentException.class, () -> 
getInstance("XXXX"));
     }
 
-    @Test
-    public void testAmPm() throws ParseException {
-        final Calendar cal= Calendar.getInstance(NEW_YORK, Locale.US);
+    @ParameterizedTest
+    @MethodSource(DATE_PARSER_PARAMETERS)
+    public void testAmPm(final TriFunction<String, TimeZone, Locale, 
DateParser> dpProvider) throws ParseException {
+        final Calendar cal = Calendar.getInstance(NEW_YORK, Locale.US);
         cal.clear();
 
-        final DateParser h = getInstance("yyyy-MM-dd hh a mm:ss", NEW_YORK, 
Locale.US);
-        final DateParser K = getInstance("yyyy-MM-dd KK a mm:ss", NEW_YORK, 
Locale.US);
-        final DateParser k = getInstance("yyyy-MM-dd kk:mm:ss", NEW_YORK, 
Locale.US);
-        final DateParser H = getInstance("yyyy-MM-dd HH:mm:ss", NEW_YORK, 
Locale.US);
+        final DateParser h = getInstance(dpProvider, "yyyy-MM-dd hh a mm:ss", 
NEW_YORK, Locale.US);
+        final DateParser K = getInstance(dpProvider, "yyyy-MM-dd KK a mm:ss", 
NEW_YORK, Locale.US);
+        final DateParser k = getInstance(dpProvider, "yyyy-MM-dd kk:mm:ss", 
NEW_YORK, Locale.US);
+        final DateParser H = getInstance(dpProvider, "yyyy-MM-dd HH:mm:ss", 
NEW_YORK, Locale.US);
 
         cal.set(2010, Calendar.AUGUST, 1, 0, 33, 20);
         assertEquals(cal.getTime(), h.parse("2010-08-01 12 AM 33:20"));
@@ -285,20 +289,21 @@ public class FastDateParserTest {
         assertEquals(Calendar.SUNDAY, calendar.get(Calendar.DAY_OF_WEEK));
     }
 
-    @Test
-    public void testDayOf() throws ParseException {
-        final Calendar cal= Calendar.getInstance(NEW_YORK, Locale.US);
+    @ParameterizedTest
+    @MethodSource(DATE_PARSER_PARAMETERS)
+    public void testDayOf(final TriFunction<String, TimeZone, Locale, 
DateParser> dpProvider) throws ParseException {
+        final Calendar cal = Calendar.getInstance(NEW_YORK, Locale.US);
         cal.clear();
         cal.set(2003, Calendar.FEBRUARY, 10);
 
-        final DateParser fdf = getInstance("W w F D y", NEW_YORK, Locale.US);
+        final DateParser fdf = getInstance(dpProvider, "W w F D y", NEW_YORK, 
Locale.US);
         assertEquals(cal.getTime(), fdf.parse("3 7 2 41 03"));
     }
 
     @Test
     public void testEquals() {
-        final DateParser parser1= getInstance(YMD_SLASH);
-        final DateParser parser2= getInstance(YMD_SLASH);
+        final DateParser parser1 = getInstance(YMD_SLASH);
+        final DateParser parser2 = getInstance(YMD_SLASH);
 
         assertEquals(parser1, parser2);
         assertEquals(parser1.hashCode(), parser2.hashCode());
@@ -306,10 +311,13 @@ public class FastDateParserTest {
         assertNotEquals(parser1, new Object());
     }
 
+    /**
+     * @throws ParseException
+     */
     @Test
     public void testJpLocales() throws ParseException {
 
-        final Calendar cal= Calendar.getInstance(GMT);
+        final Calendar cal = Calendar.getInstance(GMT);
         cal.clear();
         cal.set(2003, Calendar.FEBRUARY, 10);
         cal.set(Calendar.ERA, GregorianCalendar.BC);
@@ -324,21 +332,24 @@ public class FastDateParserTest {
         checkParse(locale, cal, sdf, fdf);
     }
 
-    @Test
-    public void testLANG_831() throws Exception {
-        testSdfAndFdp("M E", "3  Tue", true);
+    @ParameterizedTest
+    @MethodSource(DATE_PARSER_PARAMETERS)
+    public void testLANG_831(final TriFunction<String, TimeZone, Locale, 
DateParser> dpProvider) throws Exception {
+        testSdfAndFdp(dpProvider, "M E", "3  Tue", true);
     }
 
-    @Test
-    public void testLANG_832() throws Exception {
-        testSdfAndFdp("'d'd", "d3", false); // OK
-        testSdfAndFdp("'d'd'", "d3", true); // should fail (unterminated quote)
+    @ParameterizedTest
+    @MethodSource(DATE_PARSER_PARAMETERS)
+    public void testLANG_832(final TriFunction<String, TimeZone, Locale, 
DateParser> dpProvider) throws Exception {
+        testSdfAndFdp(dpProvider, "'d'd", "d3", false); // OK
+        testSdfAndFdp(dpProvider, "'d'd'", "d3", true); // should fail 
(unterminated quote)
     }
 
-    @Test
-    public void testLang1121() throws ParseException {
+    @ParameterizedTest
+    @MethodSource(DATE_PARSER_PARAMETERS)
+    public void testLang1121(final TriFunction<String, TimeZone, Locale, 
DateParser> dpProvider) throws ParseException {
         final TimeZone kst = TimeZone.getTimeZone("KST");
-        final DateParser fdp = getInstance("yyyyMMdd", kst, Locale.KOREA);
+        final DateParser fdp = getInstance(dpProvider, "yyyyMMdd", kst, 
Locale.KOREA);
 
         assertThrows(ParseException.class, () -> fdp.parse("2015"));
 
@@ -359,13 +370,14 @@ public class FastDateParserTest {
         assertEquals(expected, actual);
     }
 
-    @Test
-    public void testLang1380() throws ParseException {
+    @ParameterizedTest
+    @MethodSource(DATE_PARSER_PARAMETERS)
+    public void testLang1380(final TriFunction<String, TimeZone, Locale, 
DateParser> dpProvider) throws ParseException {
         final Calendar expected = Calendar.getInstance(GMT, Locale.FRANCE);
         expected.clear();
         expected.set(2014, Calendar.APRIL, 14);
 
-        final DateParser fdp = getInstance("dd MMM yyyy", GMT, Locale.FRANCE);
+        final DateParser fdp = getInstance(dpProvider, "dd MMM yyyy", GMT, 
Locale.FRANCE);
         assertEquals(expected.getTime(), fdp.parse("14 avril 2014"));
         assertEquals(expected.getTime(), fdp.parse("14 avr. 2014"));
         assertEquals(expected.getTime(), fdp.parse("14 avr 2014"));
@@ -394,13 +406,14 @@ public class FastDateParserTest {
         assertEquals(cal.getTime(), parser.parse("2009-10-16T16:42:16.000Z"));
     }
 
-    @Test
-    public void testLang996() throws ParseException {
+    @ParameterizedTest
+    @MethodSource(DATE_PARSER_PARAMETERS)
+    public void testLang996(final TriFunction<String, TimeZone, Locale, 
DateParser> dpProvider) throws ParseException {
         final Calendar expected = Calendar.getInstance(NEW_YORK, Locale.US);
         expected.clear();
         expected.set(2014, Calendar.MAY, 14);
 
-        final DateParser fdp = getInstance("ddMMMyyyy", NEW_YORK, Locale.US);
+        final DateParser fdp = getInstance(dpProvider, "ddMMMyyyy", NEW_YORK, 
Locale.US);
         assertEquals(expected.getTime(), fdp.parse("14may2014"));
         assertEquals(expected.getTime(), fdp.parse("14MAY2014"));
         assertEquals(expected.getTime(), fdp.parse("14May2014"));
@@ -408,74 +421,13 @@ public class FastDateParserTest {
 
     @Test
     public void testLocaleMatches() {
-        final DateParser parser= getInstance(yMdHmsSZ, SWEDEN);
+        final DateParser parser = getInstance(yMdHmsSZ, SWEDEN);
         assertEquals(SWEDEN, parser.getLocale());
     }
 
-    private void testLocales(final String format, final boolean eraBC) throws 
Exception {
-
-        final Calendar cal= Calendar.getInstance(GMT);
-        cal.clear();
-        cal.set(2003, Calendar.FEBRUARY, 10);
-        if (eraBC) {
-            cal.set(Calendar.ERA, GregorianCalendar.BC);
-        }
-
-        for (final Locale locale : Locale.getAvailableLocales() ) {
-            // ja_JP_JP cannot handle dates before 1868 properly
-            if (eraBC && locale.equals(FastDateParser.JAPANESE_IMPERIAL)) {
-                continue;
-            }
-            final SimpleDateFormat sdf = new SimpleDateFormat(format, locale);
-            final DateParser fdf = getInstance(format, locale);
-
-            // If parsing fails, a ParseException will be thrown and the test 
will fail
-            checkParse(locale, cal, sdf, fdf);
-        }
-    }
-
-    @Test
-    public void testLocales_Long_AD() throws Exception {
-        testLocales(LONG_FORMAT, false);
-    }
-
-    @Test
-    public void testLocales_Long_BC() throws Exception {
-        testLocales(LONG_FORMAT, true);
-    }
-
-    @Test
-    public void testLocales_LongNoEra_AD() throws Exception {
-        testLocales(LONG_FORMAT_NOERA, false);
-    }
-
-    @Test
-    public void testLocales_LongNoEra_BC() throws Exception {
-        testLocales(LONG_FORMAT_NOERA, true);
-    }
-
-    @Test
-    public void testLocales_Short_AD() throws Exception {
-        testLocales(SHORT_FORMAT, false);
-    }
-
-    @Test
-    public void testLocales_Short_BC() throws Exception {
-        testLocales(SHORT_FORMAT, true);
-    }
-
-    @Test
-    public void testLocales_ShortNoEra_AD() throws Exception {
-        testLocales(SHORT_FORMAT_NOERA, false);
-    }
-
-    @Test
-    public void testLocales_ShortNoEra_BC() throws Exception {
-        testLocales(SHORT_FORMAT_NOERA, true);
-    }
-
     /**
      * Tests that pre-1000AD years get padded with yyyy
+     *
      * @throws ParseException so we don't have to catch it
      */
     @Test
@@ -504,37 +456,42 @@ public class FastDateParserTest {
         assertEquals(cal.getTime(), parser.parse("01.01.1000"));
     }
 
-    @Test
-    public void testParseLongShort() throws ParseException {
-        final Calendar cal= Calendar.getInstance(NEW_YORK, Locale.US);
+    @ParameterizedTest
+    @MethodSource(DATE_PARSER_PARAMETERS)
+    public void testParseLongShort(final TriFunction<String, TimeZone, Locale, 
DateParser> dpProvider)
+        throws ParseException {
+        final Calendar cal = Calendar.getInstance(NEW_YORK, Locale.US);
         cal.clear();
         cal.set(2003, Calendar.FEBRUARY, 10, 15, 33, 20);
         cal.set(Calendar.MILLISECOND, 989);
         cal.setTimeZone(NEW_YORK);
 
-        DateParser fdf = getInstance("yyyy GGGG MMMM dddd aaaa EEEE HHHH mmmm 
ssss SSSS ZZZZ", NEW_YORK, Locale.US);
+        DateParser fdf = getInstance(dpProvider, "yyyy GGGG MMMM dddd aaaa 
EEEE HHHH mmmm ssss SSSS ZZZZ", NEW_YORK,
+            Locale.US);
 
         assertEquals(cal.getTime(), fdf.parse("2003 AD February 0010 PM Monday 
0015 0033 0020 0989 GMT-05:00"));
         cal.set(Calendar.ERA, GregorianCalendar.BC);
 
         final Date parse = fdf.parse("2003 BC February 0010 PM Saturday 0015 
0033 0020 0989 GMT-05:00");
-                assertEquals(cal.getTime(), parse);
+        assertEquals(cal.getTime(), parse);
 
-        fdf = getInstance("y G M d a E H m s S Z", NEW_YORK, Locale.US);
+        fdf = getInstance(null, "y G M d a E H m s S Z", NEW_YORK, Locale.US);
         assertEquals(cal.getTime(), fdf.parse("03 BC 2 10 PM Sat 15 33 20 989 
-0500"));
 
         cal.set(Calendar.ERA, GregorianCalendar.AD);
         assertEquals(cal.getTime(), fdf.parse("03 AD 2 10 PM Saturday 15 33 20 
989 -0500"));
     }
 
-    @Test
-    public void testParseNumerics() throws ParseException {
-        final Calendar cal= Calendar.getInstance(NEW_YORK, Locale.US);
+    @ParameterizedTest
+    @MethodSource(DATE_PARSER_PARAMETERS)
+    public void testParseNumerics(final TriFunction<String, TimeZone, Locale, 
DateParser> dpProvider)
+        throws ParseException {
+        final Calendar cal = Calendar.getInstance(NEW_YORK, Locale.US);
         cal.clear();
         cal.set(2003, Calendar.FEBRUARY, 10, 15, 33, 20);
         cal.set(Calendar.MILLISECOND, 989);
 
-        final DateParser fdf = getInstance("yyyyMMddHHmmssSSS", NEW_YORK, 
Locale.US);
+        final DateParser fdf = getInstance(dpProvider, "yyyyMMddHHmmssSSS", 
NEW_YORK, Locale.US);
         assertEquals(cal.getTime(), fdf.parse("20030210153320989"));
     }
 
@@ -552,18 +509,18 @@ public class FastDateParserTest {
     @Test
     // Check that all Locales can parse the formats we use
     public void testParses() throws Exception {
-        for (final String format : new String[]{LONG_FORMAT, SHORT_FORMAT}) {
+        for (final String format : new String[] {LONG_FORMAT, SHORT_FORMAT}) {
             for (final Locale locale : Locale.getAvailableLocales()) {
-                for (final TimeZone tz :  new TimeZone[]{NEW_YORK, REYKJAVIK, 
GMT}) {
-                     for (final int year : new int[]{2003, 1940, 1868, 1867, 
1, -1, -1940}) {
-                        final Calendar cal= getEraStart(year, tz, locale);
-                        final Date centuryStart= cal.getTime();
+                for (final TimeZone tz : new TimeZone[] {NEW_YORK, REYKJAVIK, 
GMT}) {
+                    for (final int year : new int[] {2003, 1940, 1868, 1867, 
1, -1, -1940}) {
+                        final Calendar cal = getEraStart(year, tz, locale);
+                        final Date centuryStart = cal.getTime();
 
                         cal.set(Calendar.MONTH, 1);
                         cal.set(Calendar.DAY_OF_MONTH, 10);
-                        final Date in= cal.getTime();
+                        final Date in = cal.getTime();
 
-                        final FastDateParser fdp= new FastDateParser(format, 
tz, locale, centuryStart);
+                        final FastDateParser fdp = new FastDateParser(format, 
tz, locale, centuryStart);
                         validateSdfFormatFdpParseEquality(format, locale, tz, 
fdp, in, year, centuryStart);
                     }
                 }
@@ -571,13 +528,15 @@ public class FastDateParserTest {
         }
     }
 
-    @Test
-    public void testParseZone() throws ParseException {
-        final Calendar cal= Calendar.getInstance(NEW_YORK, Locale.US);
+    @ParameterizedTest
+    @MethodSource(DATE_PARSER_PARAMETERS)
+    public void testParseZone(final TriFunction<String, TimeZone, Locale, 
DateParser> dpProvider)
+        throws ParseException {
+        final Calendar cal = Calendar.getInstance(NEW_YORK, Locale.US);
         cal.clear();
         cal.set(2003, Calendar.JULY, 10, 16, 33, 20);
 
-        final DateParser fdf = getInstance(yMdHmsSZ, NEW_YORK, Locale.US);
+        final DateParser fdf = getInstance(dpProvider, yMdHmsSZ, NEW_YORK, 
Locale.US);
 
         assertEquals(cal.getTime(), fdf.parse("2003-07-10T15:33:20.000 
-0500"));
         assertEquals(cal.getTime(), fdf.parse("2003-07-10T15:33:20.000 
GMT-05:00"));
@@ -597,23 +556,24 @@ public class FastDateParserTest {
 
     @Test
     public void testPatternMatches() {
-        final DateParser parser= getInstance(yMdHmsSZ);
+        final DateParser parser = getInstance(yMdHmsSZ);
         assertEquals(yMdHmsSZ, parser.getPattern());
     }
 
-    @Test
-    public void testQuotes() throws ParseException {
-        final Calendar cal= Calendar.getInstance(NEW_YORK, Locale.US);
+    @ParameterizedTest
+    @MethodSource(DATE_PARSER_PARAMETERS)
+    public void testQuotes(final TriFunction<String, TimeZone, Locale, 
DateParser> dpProvider) throws ParseException {
+        final Calendar cal = Calendar.getInstance(NEW_YORK, Locale.US);
         cal.clear();
         cal.set(2003, Calendar.FEBRUARY, 10, 15, 33, 20);
         cal.set(Calendar.MILLISECOND, 989);
 
-        final DateParser fdf = getInstance("''yyyyMMdd'A''B'HHmmssSSS''", 
NEW_YORK, Locale.US);
+        final DateParser fdf = getInstance(dpProvider, 
"''yyyyMMdd'A''B'HHmmssSSS''", NEW_YORK, Locale.US);
         assertEquals(cal.getTime(), fdf.parse("'20030210A'B153320989'"));
     }
 
-    private void testSdfAndFdp(final String format, final String date, final 
boolean shouldFail)
-            throws Exception {
+    private void testSdfAndFdp(final TriFunction<String, TimeZone, Locale, 
DateParser> dbProvider, final String format,
+        final String date, final boolean shouldFail) throws Exception {
         Date dfdp = null;
         Date dsdf = null;
         Throwable f = null;
@@ -623,7 +583,7 @@ public class FastDateParserTest {
             final SimpleDateFormat sdf = new SimpleDateFormat(format, 
Locale.US);
             sdf.setTimeZone(NEW_YORK);
             dsdf = sdf.parse(date);
-            assertFalse(shouldFail, "Expected SDF failure, but got " + dsdf + 
" for ["+format+", "+date+"]");
+            assertFalse(shouldFail, "Expected SDF failure, but got " + dsdf + 
" for [" + format + ", " + date + "]");
         } catch (final Exception e) {
             s = e;
             if (!shouldFail) {
@@ -632,9 +592,9 @@ public class FastDateParserTest {
         }
 
         try {
-            final DateParser fdp = getInstance(format, NEW_YORK, Locale.US);
+            final DateParser fdp = getInstance(dbProvider, format, NEW_YORK, 
Locale.US);
             dfdp = fdp.parse(date);
-            assertFalse(shouldFail, "Expected FDF failure, but got " + dfdp + 
" for ["+format+", "+date+"]");
+            assertFalse(shouldFail, "Expected FDF failure, but got " + dfdp + 
" for [" + format + ", " + date + "]");
         } catch (final Exception e) {
             f = e;
             if (!shouldFail) {
@@ -648,6 +608,7 @@ public class FastDateParserTest {
 
     /**
      * Test case for {@link FastDateParser#FastDateParser(String, TimeZone, 
Locale)}.
+     *
      * @throws ParseException so we don't have to catch it
      */
     @Test
@@ -663,44 +624,35 @@ public class FastDateParserTest {
         assertEquals(cal.getTime(), fdf.parse("2004-02-03"));
     }
 
-    private void testSingleLocale(final Locale locale) throws ParseException {
-        final Calendar cal = Calendar.getInstance(GMT);
-        cal.clear();
-        cal.set(2003, Calendar.FEBRUARY, 10);
-        final SimpleDateFormat sdf = new SimpleDateFormat(LONG_FORMAT, locale);
-        final String formattedDate = sdf.format(cal.getTime());
-        sdf.parse(formattedDate);
-        sdf.parse(formattedDate.toUpperCase(locale));
-        sdf.parse(formattedDate.toLowerCase(locale));
-    }
-
-    @Test
-    public void testSpecialCharacters() throws Exception {
-        testSdfAndFdp("q", "", true); // bad pattern character (at present)
-        testSdfAndFdp("Q", "", true); // bad pattern character
-        testSdfAndFdp("$", "$", false); // OK
-        testSdfAndFdp("?.d", "?.12", false); // OK
-        testSdfAndFdp("''yyyyMMdd'A''B'HHmmssSSS''", "'20030210A'B153320989'", 
false); // OK
-        testSdfAndFdp("''''yyyyMMdd'A''B'HHmmssSSS''", 
"''20030210A'B153320989'", false); // OK
-        testSdfAndFdp("'$\\Ed'", "$\\Ed", false); // OK
+    @ParameterizedTest
+    @MethodSource(DATE_PARSER_PARAMETERS)
+    public void testSpecialCharacters(final TriFunction<String, TimeZone, 
Locale, DateParser> dpProvider)
+        throws Exception {
+        testSdfAndFdp(dpProvider, "q", "", true); // bad pattern character (at 
present)
+        testSdfAndFdp(dpProvider, "Q", "", true); // bad pattern character
+        testSdfAndFdp(dpProvider, "$", "$", false); // OK
+        testSdfAndFdp(dpProvider, "?.d", "?.12", false); // OK
+        testSdfAndFdp(dpProvider, "''yyyyMMdd'A''B'HHmmssSSS''", 
"'20030210A'B153320989'", false); // OK
+        testSdfAndFdp(dpProvider, "''''yyyyMMdd'A''B'HHmmssSSS''", 
"''20030210A'B153320989'", false); // OK
+        testSdfAndFdp(dpProvider, "'$\\Ed'", "$\\Ed", false); // OK
 
         // quoted charaters are case sensitive
-        testSdfAndFdp("'QED'", "QED", false);
-        testSdfAndFdp("'QED'", "qed", true);
+        testSdfAndFdp(dpProvider, "'QED'", "QED", false);
+        testSdfAndFdp(dpProvider, "'QED'", "qed", true);
         // case sensitive after insensitive Month field
-        testSdfAndFdp("yyyy-MM-dd 'QED'", "2003-02-10 QED", false);
-        testSdfAndFdp("yyyy-MM-dd 'QED'", "2003-02-10 qed", true);
+        testSdfAndFdp(dpProvider, "yyyy-MM-dd 'QED'", "2003-02-10 QED", false);
+        testSdfAndFdp(dpProvider, "yyyy-MM-dd 'QED'", "2003-02-10 qed", true);
     }
 
     @Test
     public void testTimeZoneMatches() {
-        final DateParser parser= getInstance(yMdHmsSZ, REYKJAVIK);
+        final DateParser parser = getInstance(yMdHmsSZ, REYKJAVIK);
         assertEquals(REYKJAVIK, parser.getTimeZone());
     }
 
     @Test
     public void testToStringContainsName() {
-        final DateParser parser= getInstance(YMD_SLASH);
+        final DateParser parser = getInstance(YMD_SLASH);
         assertTrue(parser.toString().startsWith("FastDate"));
     }
 
@@ -710,32 +662,33 @@ public class FastDateParserTest {
     public void testTzParses() throws Exception {
         // Check that all Locales can parse the time formats we use
         for (final Locale locale : Locale.getAvailableLocales()) {
-            final FastDateParser fdp= new FastDateParser("yyyy/MM/dd z", 
TimeZone.getDefault(), locale);
+            final FastDateParser fdp = new FastDateParser("yyyy/MM/dd z", 
TimeZone.getDefault(), locale);
 
-            for (final TimeZone tz :  new TimeZone[]{NEW_YORK, REYKJAVIK, 
GMT}) {
-                final Calendar cal= Calendar.getInstance(tz, locale);
+            for (final TimeZone tz : new TimeZone[] {NEW_YORK, REYKJAVIK, 
GMT}) {
+                final Calendar cal = Calendar.getInstance(tz, locale);
                 cal.clear();
                 cal.set(Calendar.YEAR, 2000);
                 cal.set(Calendar.MONTH, 1);
                 cal.set(Calendar.DAY_OF_MONTH, 10);
-                final Date expected= cal.getTime();
+                final Date expected = cal.getTime();
 
-                final Date actual = fdp.parse("2000/02/10 
"+tz.getDisplayName(locale));
-                assertEquals(expected, actual, "tz:"+tz.getID()+" 
locale:"+locale.getDisplayName());
+                final Date actual = fdp.parse("2000/02/10 " + 
tz.getDisplayName(locale));
+                assertEquals(expected, actual, "tz:" + tz.getID() + " locale:" 
+ locale.getDisplayName());
             }
         }
     }
 
-    private void validateSdfFormatFdpParseEquality(final String format, final 
Locale locale, final TimeZone tz, final DateParser fdp, final Date in, final 
int year, final Date cs) throws ParseException {
+    private void validateSdfFormatFdpParseEquality(final String format, final 
Locale locale, final TimeZone tz,
+        final DateParser fdp, final Date in, final int year, final Date cs) 
throws ParseException {
         final SimpleDateFormat sdf = new SimpleDateFormat(format, locale);
         sdf.setTimeZone(tz);
         if (format.equals(SHORT_FORMAT)) {
-            sdf.set2DigitYearStart( cs );
+            sdf.set2DigitYearStart(cs);
         }
         final String fmt = sdf.format(in);
         try {
             final Date out = fdp.parse(fmt);
-            assertEquals(in, out, locale.toString()+" "+in+" "+ format+ " 
"+tz.getID());
+            assertEquals(in, out, locale.toString() + " " + in + " " + format 
+ " " + tz.getID());
         } catch (final ParseException pe) {
             if (year >= 1868 || !locale.getCountry().equals("JP")) {// LANG-978
                 throw pe;
@@ -743,3 +696,4 @@ public class FastDateParserTest {
         }
     }
 }
+
diff --git 
a/src/test/java/org/apache/commons/lang3/time/Java15BugFastDateParserTest.java 
b/src/test/java/org/apache/commons/lang3/time/Java15BugFastDateParserTest.java
new file mode 100644
index 0000000..15221d1
--- /dev/null
+++ 
b/src/test/java/org/apache/commons/lang3/time/Java15BugFastDateParserTest.java
@@ -0,0 +1,156 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.lang3.time;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+import java.util.Locale;
+import java.util.TimeZone;
+
+import org.apache.commons.lang3.function.TriFunction;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.MethodSource;
+
+/**
+ * These tests fail on Java 15 due to a bug which was only fixed for Java 16.
+ * <ul>
+ * <li>https://bugs.openjdk.java.net/browse/JDK-8248434</li>
+ * <li>https://bugs.openjdk.java.net/browse/JDK-8248655</li>
+ * </ul>
+ */
+public class Java15BugFastDateParserTest {
+
+    private static final String DATE_PARSER_PARAMETERS = 
"org.apache.commons.lang3.time.FastDateParserTest#dateParserParameters()";
+
+    @Test
+    public void java15BuggyLocaleTest() throws ParseException {
+        final String buggyLocaleName = "ff_LR_#Adlm";
+        Locale buggyLocale = null;
+        for (final Locale locale : Locale.getAvailableLocales()) {
+            if (buggyLocaleName.equals(locale.toString())) {
+                buggyLocale = locale;
+                break;
+            }
+        }
+        if (buggyLocale == null) {
+            return;
+        }
+        testSingleLocale(buggyLocale);
+    }
+
+    @Test
+    public void java15BuggyLocaleTestAll() throws ParseException {
+        for (final Locale locale : Locale.getAvailableLocales()) {
+            testSingleLocale(locale);
+        }
+    }
+
+    private void testLocales(final TriFunction<String, TimeZone, Locale, 
DateParser> dbProvider, final String format,
+        final boolean eraBC) throws Exception {
+
+        final Calendar cal = Calendar.getInstance(FastDateParserTest.GMT);
+        cal.clear();
+        cal.set(2003, Calendar.FEBRUARY, 10);
+        if (eraBC) {
+            cal.set(Calendar.ERA, GregorianCalendar.BC);
+        }
+
+        for (final Locale locale : Locale.getAvailableLocales()) {
+            // ja_JP_JP cannot handle dates before 1868 properly
+            if (eraBC && locale.equals(FastDateParser.JAPANESE_IMPERIAL)) {
+                continue;
+            }
+            final SimpleDateFormat sdf = new SimpleDateFormat(format, locale);
+            final DateParser fdf = dbProvider.apply(format, 
TimeZone.getDefault(), locale);
+
+            // If parsing fails, a ParseException will be thrown and the test 
will fail
+            FastDateParserTest.checkParse(locale, cal, sdf, fdf);
+        }
+    }
+
+    @ParameterizedTest
+    @MethodSource(DATE_PARSER_PARAMETERS)
+    public void testLocales_Long_AD(final TriFunction<String, TimeZone, 
Locale, DateParser> dpProvider)
+        throws Exception {
+        testLocales(dpProvider, FastDateParserTest.LONG_FORMAT, false);
+    }
+
+    @ParameterizedTest
+    @MethodSource(DATE_PARSER_PARAMETERS)
+    public void testLocales_Long_BC(final TriFunction<String, TimeZone, 
Locale, DateParser> dpProvider)
+        throws Exception {
+        testLocales(dpProvider, FastDateParserTest.LONG_FORMAT, true);
+    }
+
+    @ParameterizedTest
+    @MethodSource(DATE_PARSER_PARAMETERS)
+    public void testLocales_LongNoEra_AD(final TriFunction<String, TimeZone, 
Locale, DateParser> dpProvider)
+        throws Exception {
+        testLocales(dpProvider, FastDateParserTest.LONG_FORMAT_NOERA, false);
+    }
+
+    @ParameterizedTest
+    @MethodSource(DATE_PARSER_PARAMETERS)
+    public void testLocales_LongNoEra_BC(final TriFunction<String, TimeZone, 
Locale, DateParser> dpProvider)
+        throws Exception {
+        testLocales(dpProvider, FastDateParserTest.LONG_FORMAT_NOERA, true);
+    }
+
+    @ParameterizedTest
+    @MethodSource(DATE_PARSER_PARAMETERS)
+    public void testLocales_Short_AD(final TriFunction<String, TimeZone, 
Locale, DateParser> dpProvider)
+        throws Exception {
+        testLocales(dpProvider, FastDateParserTest.SHORT_FORMAT, false);
+    }
+
+    @ParameterizedTest
+    @MethodSource(DATE_PARSER_PARAMETERS)
+    public void testLocales_Short_BC(final TriFunction<String, TimeZone, 
Locale, DateParser> dpProvider)
+        throws Exception {
+        testLocales(dpProvider, FastDateParserTest.SHORT_FORMAT, true);
+    }
+
+    @ParameterizedTest
+    @MethodSource(DATE_PARSER_PARAMETERS)
+    public void testLocales_ShortNoEra_AD(final TriFunction<String, TimeZone, 
Locale, DateParser> dpProvider)
+        throws Exception {
+        testLocales(dpProvider, FastDateParserTest.SHORT_FORMAT_NOERA, false);
+    }
+
+    @ParameterizedTest
+    @MethodSource(DATE_PARSER_PARAMETERS)
+    public void testLocales_ShortNoEra_BC(final TriFunction<String, TimeZone, 
Locale, DateParser> dpProvider)
+        throws Exception {
+        testLocales(dpProvider, FastDateParserTest.SHORT_FORMAT_NOERA, true);
+    }
+
+    private void testSingleLocale(final Locale locale) throws ParseException {
+        final Calendar cal = Calendar.getInstance(FastDateParserTest.GMT);
+        cal.clear();
+        cal.set(2003, Calendar.FEBRUARY, 10);
+        final SimpleDateFormat sdf = new 
SimpleDateFormat(FastDateParserTest.LONG_FORMAT, locale);
+        final String formattedDate = sdf.format(cal.getTime());
+        sdf.parse(formattedDate);
+        sdf.parse(formattedDate.toUpperCase(locale));
+        sdf.parse(formattedDate.toLowerCase(locale));
+    }
+
+}
\ No newline at end of file

Reply via email to