--- old/src/java.base/share/classes/java/time/format/DateTimeFormatter.java 2017-11-10 15:30:17.390311855 -0800 +++ new/src/java.base/share/classes/java/time/format/DateTimeFormatter.java 2017-11-10 15:30:17.064305761 -0800 @@ -97,6 +97,7 @@ import java.util.Map; import java.util.Objects; import java.util.Set; +import sun.util.locale.provider.TimeZoneNameUtility; /** * Formatter for printing and parsing date-time objects. @@ -129,7 +130,12 @@ * The {@link #withLocale withLocale} method returns a new formatter that * overrides the locale. The locale affects some aspects of formatting and * parsing. For example, the {@link #ofLocalizedDate ofLocalizedDate} provides a - * formatter that uses the locale specific date format. + * formatter that uses the locale specific date format. If the locale contains + * "ca" (calendar), "rg" (region override) and/or "tz" (timezone) + * Unicode extensions, + * the chronology and/or the zone are also overriden. If both "ca" and "rg" are + * specified, the chronology from "ca" extension supersedes the implicit one + * from "rg" extension. *

* The {@link #withChronology withChronology} method returns a new formatter * that overrides the chronology. If overridden, the date-time value is @@ -548,8 +554,13 @@ * For example, {@code d MMM uuuu} will format 2011-12-03 as '3 Dec 2011'. *

* The formatter will use the {@link Locale#getDefault(Locale.Category) default FORMAT locale}. - * This can be changed using {@link DateTimeFormatter#withLocale(Locale)} on the returned formatter + * This can be changed using {@link DateTimeFormatter#withLocale(Locale)} on the returned formatter. * Alternatively use the {@link #ofPattern(String, Locale)} variant of this method. + * If the default locale contains "ca" (calendar), "rg" (region override) and/or "tz" (timezone) + * Unicode extensions, + * the chronology and/or the zone are overriden. If both "ca" and "rg" are + * specified, the chronology from "ca" extension supersedes the implicit one + * from "rg" extension. *

* The returned formatter has no override chronology or zone. * It uses {@link ResolverStyle#SMART SMART} resolver style. @@ -572,7 +583,12 @@ * For example, {@code d MMM uuuu} will format 2011-12-03 as '3 Dec 2011'. *

* The formatter will use the specified locale. - * This can be changed using {@link DateTimeFormatter#withLocale(Locale)} on the returned formatter + * This can be changed using {@link DateTimeFormatter#withLocale(Locale)} on the returned formatter. + * If the specified locale contains "ca" (calendar), "rg" (region override) and/or "tz" (timezone) + * Unicode extensions, + * the chronology and/or the zone are overriden. If both "ca" and "rg" are + * specified, the chronology from "ca" extension supersedes the implicit one + * from "rg" extension. *

* The returned formatter has no override chronology or zone. * It uses {@link ResolverStyle#SMART SMART} resolver style. @@ -1441,7 +1457,12 @@ * Returns a copy of this formatter with a new locale. *

* This is used to lookup any part of the formatter needing specific - * localization, such as the text or localized pattern. + * localization, such as the text or localized pattern. If the new + * locale contains "ca" (calendar), "rg" (region override) and/or "tz" (timezone) + * Unicode extensions, + * the chronology and/or the zone are also overriden. If both "ca" and "rg" are + * specified, the chronology from "ca" extension supersedes the implicit one + * from "rg" extension. *

* This instance is immutable and unaffected by this method call. * @@ -1452,7 +1473,17 @@ if (this.locale.equals(locale)) { return this; } - return new DateTimeFormatter(printerParser, locale, decimalStyle, resolverStyle, resolverFields, chrono, zone); + + // Check for chronology/timezone in locale object + Chronology c = locale.getUnicodeLocaleType("ca") != null ? + Chronology.ofLocale(locale) : chrono; + String tzType = locale.getUnicodeLocaleType("tz"); + ZoneId z = tzType != null ? + TimeZoneNameUtility.convertLDMLShortID(tzType) + .map(ZoneId::of) + .orElse(zone) : + zone; + return new DateTimeFormatter(printerParser, locale, decimalStyle, resolverStyle, resolverFields, c, z); } //-----------------------------------------------------------------------