--- old/src/java.base/share/classes/sun/util/locale/provider/CalendarDataUtility.java 2017-11-10 15:30:29.893545571 -0800 +++ new/src/java.base/share/classes/sun/util/locale/provider/CalendarDataUtility.java 2017-11-10 15:30:29.558539309 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,6 +28,7 @@ import static java.util.Calendar.*; import java.util.Locale; import java.util.Map; +import java.util.Optional; import java.util.spi.CalendarDataProvider; import java.util.spi.CalendarNameProvider; @@ -47,10 +48,34 @@ } public static int retrieveFirstDayOfWeek(Locale locale) { + // Look for the Unicode Extension in the locale parameter + if (locale.hasExtensions()) { + String fw = locale.getUnicodeLocaleType("fw"); + if (fw != null) { + switch (fw.toLowerCase(Locale.ROOT)) { + case "mon": + return MONDAY; + case "tue": + return TUESDAY; + case "wed": + return WEDNESDAY; + case "thu": + return THURSDAY; + case "fri": + return FRIDAY; + case "sat": + return SATURDAY; + case "sun": + return SUNDAY; + } + } + } + LocaleServiceProviderPool pool = LocaleServiceProviderPool.getPool(CalendarDataProvider.class); Integer value = pool.getLocalizedObject(CalendarWeekParameterGetter.INSTANCE, - locale, true, FIRST_DAY_OF_WEEK); + findRegionOverride(locale).orElse(locale), + true, FIRST_DAY_OF_WEEK); return (value != null && (value >= SUNDAY && value <= SATURDAY)) ? value : SUNDAY; } @@ -58,7 +83,8 @@ LocaleServiceProviderPool pool = LocaleServiceProviderPool.getPool(CalendarDataProvider.class); Integer value = pool.getLocalizedObject(CalendarWeekParameterGetter.INSTANCE, - locale, true, MINIMAL_DAYS_IN_FIRST_WEEK); + findRegionOverride(locale).orElse(locale), + true, MINIMAL_DAYS_IN_FIRST_WEEK); return (value != null && (value >= 1 && value <= 7)) ? value : 1; } @@ -102,6 +128,31 @@ return map; } + /** + * Utility to look for a region override extension + */ + public static Optional findRegionOverride(Locale l) { + String rg = l.getUnicodeLocaleType("rg"); + Locale override = null; + + if (rg != null && rg.length() == 6) { + // UN M.49 code should not be allowed here + // cannot use regex here, as it could be a recursive call + rg = rg.toUpperCase(Locale.ROOT); + if (rg.charAt(0) >= 0x0041 && + rg.charAt(0) <= 0x005A && + rg.charAt(1) >= 0x0041 && + rg.charAt(1) <= 0x005A && + rg.substring(2).equals("ZZZZ")) { + override = new Locale.Builder().setLocale(l) + .setRegion(rg.substring(0, 2)) + .build(); + } + } + + return Optional.ofNullable(override); + } + static String normalizeCalendarType(String requestID) { String type; if (requestID.equals("gregorian") || requestID.equals("iso8601")) { @@ -179,7 +230,7 @@ } } - private static class CalendarWeekParameterGetter + private static class CalendarWeekParameterGetter implements LocaleServiceProviderPool.LocalizedObjectGetter { private static final CalendarWeekParameterGetter INSTANCE =