View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      https://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.commons.lang3.time;
19  
20  import java.text.ParseException;
21  import java.text.SimpleDateFormat;
22  import java.util.Calendar;
23  import java.util.GregorianCalendar;
24  import java.util.Locale;
25  import java.util.TimeZone;
26  
27  import org.apache.commons.lang3.AbstractLangTest;
28  import org.apache.commons.lang3.function.TriFunction;
29  import org.junit.jupiter.api.Test;
30  import org.junit.jupiter.params.ParameterizedTest;
31  import org.junit.jupiter.params.provider.MethodSource;
32  
33  /**
34   * These tests fail on Java 15 due to a bug which was only fixed for Java 16.
35   * <ul>
36   * <li>https://bugs.openjdk.java.net/browse/JDK-8248434</li>
37   * <li>https://bugs.openjdk.java.net/browse/JDK-8248655</li>
38   * </ul>
39   */
40  class Java15BugFastDateParserTest extends AbstractLangTest {
41  
42      /** @see org.apache.commons.lang3.time.FastDateParserTest#dateParserParameters() */
43      private static final String DATE_PARSER_PARAMETERS = "org.apache.commons.lang3.time.FastDateParserTest#dateParserParameters()";
44  
45      @Test
46      void testJava15BuggyLocaleTest() throws ParseException {
47          final String buggyLocaleName = "ff_LR_#Adlm";
48          Locale buggyLocale = null;
49          for (final Locale locale : Locale.getAvailableLocales()) {
50              if (buggyLocaleName.equals(locale.toString())) {
51                  buggyLocale = locale;
52                  break;
53              }
54          }
55          if (buggyLocale == null) {
56              return;
57          }
58          testSingleLocale(buggyLocale);
59      }
60  
61      @ParameterizedTest
62      @MethodSource("org.apache.commons.lang3.LocaleUtils#availableLocaleList()")
63      void testJava15BuggyLocaleTestAll(final Locale locale) throws ParseException {
64          testSingleLocale(locale);
65      }
66  
67      private void testLocales(final TriFunction<String, TimeZone, Locale, DateParser> dbProvider, final String format,
68              final boolean eraBC) throws Exception {
69          final Calendar cal = Calendar.getInstance(TimeZones.GMT);
70          cal.clear();
71          cal.set(2003, Calendar.FEBRUARY, 10);
72          if (eraBC) {
73              cal.set(Calendar.ERA, GregorianCalendar.BC);
74          }
75          for (final Locale locale : Locale.getAvailableLocales()) {
76              // ja_JP_JP cannot handle dates before 1868 properly
77              if (eraBC && locale.equals(FastDateParser.JAPANESE_IMPERIAL)) {
78                  continue;
79              }
80              final SimpleDateFormat sdf = new SimpleDateFormat(format, locale);
81              final DateParser fdf = dbProvider.apply(format, TimeZone.getDefault(), locale);
82              // If parsing fails, a ParseException will be thrown and the test will fail
83              FastDateParserTest.checkParse(locale, cal, sdf, fdf);
84          }
85      }
86  
87      @ParameterizedTest
88      @MethodSource(DATE_PARSER_PARAMETERS)
89      void testLocales_Long_AD(final TriFunction<String, TimeZone, Locale, DateParser> dpProvider)
90          throws Exception {
91          testLocales(dpProvider, FastDateParserTest.LONG_FORMAT, false);
92      }
93  
94      @ParameterizedTest
95      @MethodSource(DATE_PARSER_PARAMETERS)
96      void testLocales_Long_BC(final TriFunction<String, TimeZone, Locale, DateParser> dpProvider)
97          throws Exception {
98          testLocales(dpProvider, FastDateParserTest.LONG_FORMAT, true);
99      }
100 
101     @ParameterizedTest
102     @MethodSource(DATE_PARSER_PARAMETERS)
103     void testLocales_LongNoEra_AD(final TriFunction<String, TimeZone, Locale, DateParser> dpProvider)
104         throws Exception {
105         testLocales(dpProvider, FastDateParserTest.LONG_FORMAT_NOERA, false);
106     }
107 
108     @ParameterizedTest
109     @MethodSource(DATE_PARSER_PARAMETERS)
110     void testLocales_LongNoEra_BC(final TriFunction<String, TimeZone, Locale, DateParser> dpProvider)
111         throws Exception {
112         testLocales(dpProvider, FastDateParserTest.LONG_FORMAT_NOERA, true);
113     }
114 
115     @ParameterizedTest
116     @MethodSource(DATE_PARSER_PARAMETERS)
117     void testLocales_Short_AD(final TriFunction<String, TimeZone, Locale, DateParser> dpProvider)
118         throws Exception {
119         testLocales(dpProvider, FastDateParserTest.SHORT_FORMAT, false);
120     }
121 
122     @ParameterizedTest
123     @MethodSource(DATE_PARSER_PARAMETERS)
124     void testLocales_Short_BC(final TriFunction<String, TimeZone, Locale, DateParser> dpProvider)
125         throws Exception {
126         testLocales(dpProvider, FastDateParserTest.SHORT_FORMAT, true);
127     }
128 
129     @ParameterizedTest
130     @MethodSource(DATE_PARSER_PARAMETERS)
131     void testLocales_ShortNoEra_AD(final TriFunction<String, TimeZone, Locale, DateParser> dpProvider)
132         throws Exception {
133         testLocales(dpProvider, FastDateParserTest.SHORT_FORMAT_NOERA, false);
134     }
135 
136     @ParameterizedTest
137     @MethodSource(DATE_PARSER_PARAMETERS)
138     void testLocales_ShortNoEra_BC(final TriFunction<String, TimeZone, Locale, DateParser> dpProvider)
139         throws Exception {
140         testLocales(dpProvider, FastDateParserTest.SHORT_FORMAT_NOERA, true);
141     }
142 
143     private void testSingleLocale(final Locale locale) throws ParseException {
144         final Calendar cal = Calendar.getInstance(TimeZones.GMT);
145         cal.clear();
146         cal.set(2003, Calendar.FEBRUARY, 10);
147         final SimpleDateFormat sdf = new SimpleDateFormat(FastDateParserTest.LONG_FORMAT, locale);
148         final String formattedDate = sdf.format(cal.getTime());
149         sdf.parse(formattedDate);
150         sdf.parse(formattedDate.toUpperCase(locale));
151         sdf.parse(formattedDate.toLowerCase(locale));
152     }
153 
154 }