JDK-8167143 : CLDR timezone parsing does not work for all locales
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.util:i18n
  • Affected Version: 9
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic
  • CPU: x86
  • Submitted: 2016-10-01
  • Updated: 2018-08-30
  • Resolved: 2016-12-22
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 9
9 b151Fixed
Related Reports
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.8.0_92"
Java(TM) SE Runtime Environment (build 1.8.0_92-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.92-b14, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
Darwin McBookAir 15.6.0 Darwin Kernel Version 15.6.0: Mon Aug 29 20:21:34 PDT 2016; root:xnu-3248.60.11~1/RELEASE_X86_64 x86_64


A DESCRIPTION OF THE PROBLEM :
While testing apache commons lang 3.5 on EA-9, we detected failure of timezone parsing in several locales.

REGRESSION.  Last worked in version 8u102

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compiling and running apache commons lang test suite.
See https://issues.apache.org/jira/browse/LANG-1265

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Unit test should pass

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
Run following unit test:
j
    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");

    @Test
    public void testTzParses() throws Exception {
        // Check that all Locales can parse the time formats we use
        for(final Locale locale : Locale.getAvailableLocales()) {
            final SimpleDateFormat sdf= new SimpleDateFormat("yyyy/MM/dd z", 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);
                cal.setTimeZone(tz);
                final Date expected= cal.getTime();

                final Date actual = sdf.parse("2000/02/10 "+tz.getDisplayName(locale));
                Assert.assertEquals("tz:"+tz.getID()+" locale:"+locale.getDisplayName(), expected, actual);
            }
        }
    }
---------- END SOURCE ----------


Comments
There are multiple issues behind this beahviour. For Chinese Locales, At run time, as these locales are not declared to be supported from CLDR, so COMPAT Locales precede them during resourcebundle search path at run time. So, in CLDR converter these likely subtags need to be added for those locales, which are implicitly supported by CLDR. [ zh-Hans-CN zh-Hant-HK zh-Hant-MO zh-Hant-TW zh-Hans-SG] For Thai locales, issue is that, in DateFormatSymbols class, if SimpleDateForamt instance for th_TH_TH locale, happens to be created first, then current code is unconditionally caching JRE th_TH bundle which is wrong behaviour. For zh__Hant and zh__Hans locales, retrieved list of candidate locales is not appropriate. zh_TW_Hant and zh_CN_Hans should not be first candidate locale to be looked up for those cases respectively. Another issue is that locales nb-NO and nn-NO which are equivalent of no-NO-NY should be declared as implicit locales for COMPAT for all providers.
21-12-2016

To reproduce the issue, run the attached program. Issue is, getting the ParseException for locales zh, zh_TW, zh__#Hant ,zh_CN, zh_HK and th_TH. Following are the results in different builds : JDK 8u102 - Pass JDK 8u122 ea - Pass JDK 9ea + b70 - Pass JDK 9ea + b71 - Fail JDK 9ea + 137 - Fail
04-10-2016