1 /*
2 * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
32 * materials are provided under terms of a License Agreement between Taligent
33 * and Sun. This technology is protected by multiple US and International
34 * patents. This notice and attribution to Taligent may not be removed.
35 * Taligent is a registered trademark of Taligent, Inc.
36 *
37 */
38
39 package java.text;
40
41 import java.io.IOException;
42 import java.io.ObjectOutputStream;
43 import java.io.Serializable;
44 import java.lang.ref.SoftReference;
45 import java.text.spi.DateFormatSymbolsProvider;
46 import java.util.Arrays;
47 import java.util.Locale;
48 import java.util.Objects;
49 import java.util.ResourceBundle;
50 import java.util.concurrent.ConcurrentHashMap;
51 import java.util.concurrent.ConcurrentMap;
52 import sun.util.locale.provider.LocaleProviderAdapter;
53 import sun.util.locale.provider.LocaleServiceProviderPool;
54 import sun.util.locale.provider.ResourceBundleBasedAdapter;
55 import sun.util.locale.provider.TimeZoneNameUtility;
56
57 /**
58 * <code>DateFormatSymbols</code> is a public class for encapsulating
59 * localizable date-time formatting data, such as the names of the
60 * months, the names of the days of the week, and the time zone data.
61 * <code>SimpleDateFormat</code> uses
62 * <code>DateFormatSymbols</code> to encapsulate this information.
63 *
64 * <p>
65 * Typically you shouldn't use <code>DateFormatSymbols</code> directly.
66 * Rather, you are encouraged to create a date-time formatter with the
67 * <code>DateFormat</code> class's factory methods: <code>getTimeInstance</code>,
68 * <code>getDateInstance</code>, or <code>getDateTimeInstance</code>.
69 * These methods automatically create a <code>DateFormatSymbols</code> for
70 * the formatter so that you don't have to. After the
71 * formatter is created, you may modify its format pattern using the
72 * <code>setPattern</code> method. For more information about
73 * creating formatters using <code>DateFormat</code>'s factory methods,
74 * see {@link DateFormat}.
75 *
76 * <p>
77 * If you decide to create a date-time formatter with a specific
78 * format pattern for a specific locale, you can do so with:
79 * <blockquote>
80 * <pre>
81 * new SimpleDateFormat(aPattern, DateFormatSymbols.getInstance(aLocale)).
82 * </pre>
83 * </blockquote>
84 *
85 * <p>
86 * <code>DateFormatSymbols</code> objects are cloneable. When you obtain
87 * a <code>DateFormatSymbols</code> object, feel free to modify the
88 * date-time formatting data. For instance, you can replace the localized
89 * date-time format pattern characters with the ones that you feel easy
90 * to remember. Or you can change the representative cities
91 * to your favorite ones.
92 *
93 * <p>
94 * New <code>DateFormatSymbols</code> subclasses may be added to support
95 * <code>SimpleDateFormat</code> for date-time formatting for additional locales.
96
97 * @see DateFormat
98 * @see SimpleDateFormat
99 * @see java.util.SimpleTimeZone
100 * @author Chen-Lieh Huang
101 * @since 1.1
102 */
103 public class DateFormatSymbols implements Serializable, Cloneable {
104
699 */
700 transient volatile int cachedHashCode;
701
702 /**
703 * Initializes this DateFormatSymbols with the locale data. This method uses
704 * a cached DateFormatSymbols instance for the given locale if available. If
705 * there's no cached one, this method creates an uninitialized instance and
706 * populates its fields from the resource bundle for the locale, and caches
707 * the instance. Note: zoneStrings isn't initialized in this method.
708 */
709 private void initializeData(Locale locale) {
710 SoftReference<DateFormatSymbols> ref = cachedInstances.get(locale);
711 DateFormatSymbols dfs;
712 if (ref == null || (dfs = ref.get()) == null) {
713 if (ref != null) {
714 // Remove the empty SoftReference
715 cachedInstances.remove(locale, ref);
716 }
717 dfs = new DateFormatSymbols(false);
718
719 // Initialize the fields from the ResourceBundle for locale.
720 LocaleProviderAdapter adapter
721 = LocaleProviderAdapter.getAdapter(DateFormatSymbolsProvider.class, locale);
722 // Avoid any potential recursions
723 if (!(adapter instanceof ResourceBundleBasedAdapter)) {
724 adapter = LocaleProviderAdapter.getResourceBundleBased();
725 }
726 ResourceBundle resource
727 = ((ResourceBundleBasedAdapter)adapter).getLocaleData().getDateFormatData(locale);
728
729 dfs.locale = locale;
730 // JRE and CLDR use different keys
731 // JRE: Eras, short.Eras and narrow.Eras
732 // CLDR: long.Eras, Eras and narrow.Eras
733 if (resource.containsKey("Eras")) {
734 dfs.eras = resource.getStringArray("Eras");
735 } else if (resource.containsKey("long.Eras")) {
736 dfs.eras = resource.getStringArray("long.Eras");
737 } else if (resource.containsKey("short.Eras")) {
738 dfs.eras = resource.getStringArray("short.Eras");
739 }
740 dfs.months = resource.getStringArray("MonthNames");
741 dfs.shortMonths = resource.getStringArray("MonthAbbreviations");
742 dfs.ampms = resource.getStringArray("AmPmMarkers");
743 dfs.localPatternChars = resource.getString("DateTimePatternChars");
744
745 // Day of week names are stored in a 1-based array.
746 dfs.weekdays = toOneBasedArray(resource.getStringArray("DayNames"));
747 dfs.shortWeekdays = toOneBasedArray(resource.getStringArray("DayAbbreviations"));
|
1 /*
2 * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
32 * materials are provided under terms of a License Agreement between Taligent
33 * and Sun. This technology is protected by multiple US and International
34 * patents. This notice and attribution to Taligent may not be removed.
35 * Taligent is a registered trademark of Taligent, Inc.
36 *
37 */
38
39 package java.text;
40
41 import java.io.IOException;
42 import java.io.ObjectOutputStream;
43 import java.io.Serializable;
44 import java.lang.ref.SoftReference;
45 import java.text.spi.DateFormatSymbolsProvider;
46 import java.util.Arrays;
47 import java.util.Locale;
48 import java.util.Objects;
49 import java.util.ResourceBundle;
50 import java.util.concurrent.ConcurrentHashMap;
51 import java.util.concurrent.ConcurrentMap;
52 import sun.util.locale.provider.CalendarDataUtility;
53 import sun.util.locale.provider.LocaleProviderAdapter;
54 import sun.util.locale.provider.LocaleServiceProviderPool;
55 import sun.util.locale.provider.ResourceBundleBasedAdapter;
56 import sun.util.locale.provider.TimeZoneNameUtility;
57
58 /**
59 * <code>DateFormatSymbols</code> is a public class for encapsulating
60 * localizable date-time formatting data, such as the names of the
61 * months, the names of the days of the week, and the time zone data.
62 * <code>SimpleDateFormat</code> uses
63 * <code>DateFormatSymbols</code> to encapsulate this information.
64 *
65 * <p>
66 * Typically you shouldn't use <code>DateFormatSymbols</code> directly.
67 * Rather, you are encouraged to create a date-time formatter with the
68 * <code>DateFormat</code> class's factory methods: <code>getTimeInstance</code>,
69 * <code>getDateInstance</code>, or <code>getDateTimeInstance</code>.
70 * These methods automatically create a <code>DateFormatSymbols</code> for
71 * the formatter so that you don't have to. After the
72 * formatter is created, you may modify its format pattern using the
73 * <code>setPattern</code> method. For more information about
74 * creating formatters using <code>DateFormat</code>'s factory methods,
75 * see {@link DateFormat}.
76 *
77 * <p>
78 * If you decide to create a date-time formatter with a specific
79 * format pattern for a specific locale, you can do so with:
80 * <blockquote>
81 * <pre>
82 * new SimpleDateFormat(aPattern, DateFormatSymbols.getInstance(aLocale)).
83 * </pre>
84 * </blockquote>
85 *
86 * <p>If the locale contains "rg" (region override)
87 * <a href="../util/Locale.html#def_locale_extension">Unicode extension</a>,
88 * the symbols are overriden for the designated region.
89 *
90 * <p>
91 * <code>DateFormatSymbols</code> objects are cloneable. When you obtain
92 * a <code>DateFormatSymbols</code> object, feel free to modify the
93 * date-time formatting data. For instance, you can replace the localized
94 * date-time format pattern characters with the ones that you feel easy
95 * to remember. Or you can change the representative cities
96 * to your favorite ones.
97 *
98 * <p>
99 * New <code>DateFormatSymbols</code> subclasses may be added to support
100 * <code>SimpleDateFormat</code> for date-time formatting for additional locales.
101
102 * @see DateFormat
103 * @see SimpleDateFormat
104 * @see java.util.SimpleTimeZone
105 * @author Chen-Lieh Huang
106 * @since 1.1
107 */
108 public class DateFormatSymbols implements Serializable, Cloneable {
109
704 */
705 transient volatile int cachedHashCode;
706
707 /**
708 * Initializes this DateFormatSymbols with the locale data. This method uses
709 * a cached DateFormatSymbols instance for the given locale if available. If
710 * there's no cached one, this method creates an uninitialized instance and
711 * populates its fields from the resource bundle for the locale, and caches
712 * the instance. Note: zoneStrings isn't initialized in this method.
713 */
714 private void initializeData(Locale locale) {
715 SoftReference<DateFormatSymbols> ref = cachedInstances.get(locale);
716 DateFormatSymbols dfs;
717 if (ref == null || (dfs = ref.get()) == null) {
718 if (ref != null) {
719 // Remove the empty SoftReference
720 cachedInstances.remove(locale, ref);
721 }
722 dfs = new DateFormatSymbols(false);
723
724 // check for region override
725 Locale override = CalendarDataUtility.findRegionOverride(locale).orElse(locale);
726
727 // Initialize the fields from the ResourceBundle for locale.
728 LocaleProviderAdapter adapter
729 = LocaleProviderAdapter.getAdapter(DateFormatSymbolsProvider.class, override);
730 // Avoid any potential recursions
731 if (!(adapter instanceof ResourceBundleBasedAdapter)) {
732 adapter = LocaleProviderAdapter.getResourceBundleBased();
733 }
734 ResourceBundle resource
735 = ((ResourceBundleBasedAdapter)adapter).getLocaleData().getDateFormatData(override);
736
737 dfs.locale = locale;
738 // JRE and CLDR use different keys
739 // JRE: Eras, short.Eras and narrow.Eras
740 // CLDR: long.Eras, Eras and narrow.Eras
741 if (resource.containsKey("Eras")) {
742 dfs.eras = resource.getStringArray("Eras");
743 } else if (resource.containsKey("long.Eras")) {
744 dfs.eras = resource.getStringArray("long.Eras");
745 } else if (resource.containsKey("short.Eras")) {
746 dfs.eras = resource.getStringArray("short.Eras");
747 }
748 dfs.months = resource.getStringArray("MonthNames");
749 dfs.shortMonths = resource.getStringArray("MonthAbbreviations");
750 dfs.ampms = resource.getStringArray("AmPmMarkers");
751 dfs.localPatternChars = resource.getString("DateTimePatternChars");
752
753 // Day of week names are stored in a 1-based array.
754 dfs.weekdays = toOneBasedArray(resource.getStringArray("DayNames"));
755 dfs.shortWeekdays = toOneBasedArray(resource.getStringArray("DayAbbreviations"));
|