java.util.Locale Maven / Gradle / Ivy
/*
* Copyright (c) 1996, 2011, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
* (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved
*
* The original version of this source code and documentation
* is copyrighted and owned by Taligent, Inc., a wholly-owned
* subsidiary of IBM. These materials are provided under terms
* of a License Agreement between Taligent and Sun. This technology
* is protected by multiple US and International patents.
*
* This notice and attribution to Taligent may not be removed.
* Taligent is a registered trademark of Taligent, Inc.
*
*/
package java.util;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamField;
import java.io.Serializable;
import org.apidesign.bck2brwsr.core.JavaScriptBody;
/**
* A Locale
object represents a specific geographical, political,
* or cultural region. An operation that requires a Locale
to perform
* its task is called locale-sensitive and uses the Locale
* to tailor information for the user. For example, displaying a number
* is a locale-sensitive operation— the number should be formatted
* according to the customs and conventions of the user's native country,
* region, or culture.
*
* The Locale
class implements identifiers
* interchangeable with BCP 47 (IETF BCP 47, "Tags for Identifying
* Languages"), with support for the LDML (UTS#35, "Unicode Locale
* Data Markup Language") BCP 47-compatible extensions for locale data
* exchange.
*
*
A Locale
object logically consists of the fields
* described below.
*
*
* - language
*
* - ISO 639 alpha-2 or alpha-3 language code, or registered
* language subtags up to 8 alpha letters (for future enhancements).
* When a language has both an alpha-2 code and an alpha-3 code, the
* alpha-2 code must be used. You can find a full list of valid
* language codes in the IANA Language Subtag Registry (search for
* "Type: language"). The language field is case insensitive, but
*
Locale
always canonicalizes to lower case.
*
* - Well-formed language values have the form
*
[a-zA-Z]{2,8}
. Note that this is not the the full
* BCP47 language production, since it excludes extlang. They are
* not needed since modern three-letter language codes replace
* them.
*
* - Example: "en" (English), "ja" (Japanese), "kok" (Konkani)
*
* - script
*
* - ISO 15924 alpha-4 script code. You can find a full list of
* valid script codes in the IANA Language Subtag Registry (search
* for "Type: script"). The script field is case insensitive, but
*
Locale
always canonicalizes to title case (the first
* letter is upper case and the rest of the letters are lower
* case).
*
* - Well-formed script values have the form
*
[a-zA-Z]{4}
*
* - Example: "Latn" (Latin), "Cyrl" (Cyrillic)
*
* - country (region)
*
* - ISO 3166 alpha-2 country code or UN M.49 numeric-3 area code.
* You can find a full list of valid country and region codes in the
* IANA Language Subtag Registry (search for "Type: region"). The
* country (region) field is case insensitive, but
*
Locale
always canonicalizes to upper case.
*
* - Well-formed country/region values have
* the form
[a-zA-Z]{2} | [0-9]{3}
*
* - Example: "US" (United States), "FR" (France), "029"
* (Caribbean)
*
* - variant
*
* - Any arbitrary value used to indicate a variation of a
*
Locale
. Where there are two or more variant values
* each indicating its own semantics, these values should be ordered
* by importance, with most important first, separated by
* underscore('_'). The variant field is case sensitive.
*
* - Note: IETF BCP 47 places syntactic restrictions on variant
* subtags. Also BCP 47 subtags are strictly used to indicate
* additional variations that define a language or its dialects that
* are not covered by any combinations of language, script and
* region subtags. You can find a full list of valid variant codes
* in the IANA Language Subtag Registry (search for "Type: variant").
*
*
However, the variant field in Locale
has
* historically been used for any kind of variation, not just
* language variations. For example, some supported variants
* available in Java SE Runtime Environments indicate alternative
* cultural behaviors such as calendar type or number script. In
* BCP 47 this kind of information, which does not identify the
* language, is supported by extension subtags or private use
* subtags.
*
* - Well-formed variant values have the form
SUBTAG
* (('_'|'-') SUBTAG)*
where SUBTAG =
* [0-9][0-9a-zA-Z]{3} | [0-9a-zA-Z]{5,8}
. (Note: BCP 47 only
* uses hyphen ('-') as a delimiter, this is more lenient).
*
* - Example: "polyton" (Polytonic Greek), "POSIX"
*
* - extensions
*
* - A map from single character keys to string values, indicating
* extensions apart from language identification. The extensions in
*
Locale
implement the semantics and syntax of BCP 47
* extension subtags and private use subtags. The extensions are
* case insensitive, but Locale
canonicalizes all
* extension keys and values to lower case. Note that extensions
* cannot have empty values.
*
* - Well-formed keys are single characters from the set
*
[0-9a-zA-Z]
. Well-formed values have the form
* SUBTAG ('-' SUBTAG)*
where for the key 'x'
* SUBTAG = [0-9a-zA-Z]{1,8}
and for other keys
* SUBTAG = [0-9a-zA-Z]{2,8}
(that is, 'x' allows
* single-character subtags).
*
* - Example: key="u"/value="ca-japanese" (Japanese Calendar),
* key="x"/value="java-1-7"
*
*
* Note: Although BCP 47 requires field values to be registered
* in the IANA Language Subtag Registry, the Locale
class
* does not provide any validation features. The Builder
* only checks if an individual field satisfies the syntactic
* requirement (is well-formed), but does not validate the value
* itself. See {@link Builder} for details.
*
* Unicode locale/language extension
*
* UTS#35, "Unicode Locale Data Markup Language" defines optional
* attributes and keywords to override or refine the default behavior
* associated with a locale. A keyword is represented by a pair of
* key and type. For example, "nu-thai" indicates that Thai local
* digits (value:"thai") should be used for formatting numbers
* (key:"nu").
*
*
The keywords are mapped to a BCP 47 extension value using the
* extension key 'u' ({@link #UNICODE_LOCALE_EXTENSION}). The above
* example, "nu-thai", becomes the extension "u-nu-thai".code
*
*
Thus, when a Locale
object contains Unicode locale
* attributes and keywords,
* getExtension(UNICODE_LOCALE_EXTENSION)
will return a
* String representing this information, for example, "nu-thai". The
* Locale
class also provides {@link
* #getUnicodeLocaleAttributes}, {@link #getUnicodeLocaleKeys}, and
* {@link #getUnicodeLocaleType} which allow you to access Unicode
* locale attributes and key/type pairs directly. When represented as
* a string, the Unicode Locale Extension lists attributes
* alphabetically, followed by key/type sequences with keys listed
* alphabetically (the order of subtags comprising a key's type is
* fixed when the type is defined)
*
*
A well-formed locale key has the form
* [0-9a-zA-Z]{2}
. A well-formed locale type has the
* form "" | [0-9a-zA-Z]{3,8} ('-' [0-9a-zA-Z]{3,8})*
(it
* can be empty, or a series of subtags 3-8 alphanums in length). A
* well-formed locale attribute has the form
* [0-9a-zA-Z]{3,8}
(it is a single subtag with the same
* form as a locale type subtag).
*
*
The Unicode locale extension specifies optional behavior in
* locale-sensitive services. Although the LDML specification defines
* various keys and values, actual locale-sensitive service
* implementations in a Java Runtime Environment might not support any
* particular Unicode locale attributes or key/type pairs.
*
*
Creating a Locale
*
* There are several different ways to create a Locale
* object.
*
*
Builder
*
* Using {@link Builder} you can construct a Locale
object
* that conforms to BCP 47 syntax.
*
*
Constructors
*
* The Locale
class provides three constructors:
*
*
* {@link #Locale(String language)}
* {@link #Locale(String language, String country)}
* {@link #Locale(String language, String country, String variant)}
*
*
* These constructors allow you to create a Locale
object
* with language, country and variant, but you cannot specify
* script or extensions.
*
* Factory Methods
*
* The method {@link #forLanguageTag} creates a Locale
* object for a well-formed BCP 47 language tag.
*
*
Locale Constants
*
* The Locale
class provides a number of convenient constants
* that you can use to create Locale
objects for commonly used
* locales. For example, the following creates a Locale
object
* for the United States:
*
*
* Locale.US
*
*
*
* Use of Locale
*
* Once you've created a Locale
you can query it for information
* about itself. Use getCountry
to get the country (or region)
* code and getLanguage
to get the language code.
* You can use getDisplayCountry
to get the
* name of the country suitable for displaying to the user. Similarly,
* you can use getDisplayLanguage
to get the name of
* the language suitable for displaying to the user. Interestingly,
* the getDisplayXXX
methods are themselves locale-sensitive
* and have two versions: one that uses the default locale and one
* that uses the locale specified as an argument.
*
*
The Java Platform provides a number of classes that perform locale-sensitive
* operations. For example, the NumberFormat
class formats
* numbers, currency, and percentages in a locale-sensitive manner. Classes
* such as NumberFormat
have several convenience methods
* for creating a default object of that type. For example, the
* NumberFormat
class provides these three convenience methods
* for creating a default NumberFormat
object:
*
*
* NumberFormat.getInstance()
* NumberFormat.getCurrencyInstance()
* NumberFormat.getPercentInstance()
*
*
* Each of these methods has two variants; one with an explicit locale
* and one without; the latter uses the default locale:
*
*
* NumberFormat.getInstance(myLocale)
* NumberFormat.getCurrencyInstance(myLocale)
* NumberFormat.getPercentInstance(myLocale)
*
*
* A Locale
is the mechanism for identifying the kind of object
* (NumberFormat
) that you would like to get. The locale is
* just a mechanism for identifying objects,
* not a container for the objects themselves.
*
* Compatibility
*
* In order to maintain compatibility with existing usage, Locale's
* constructors retain their behavior prior to the Java Runtime
* Environment version 1.7. The same is largely true for the
* toString
method. Thus Locale objects can continue to
* be used as they were. In particular, clients who parse the output
* of toString into language, country, and variant fields can continue
* to do so (although this is strongly discouraged), although the
* variant field will have additional information in it if script or
* extensions are present.
*
*
In addition, BCP 47 imposes syntax restrictions that are not
* imposed by Locale's constructors. This means that conversions
* between some Locales and BCP 47 language tags cannot be made without
* losing information. Thus toLanguageTag
cannot
* represent the state of locales whose language, country, or variant
* do not conform to BCP 47.
*
*
Because of these issues, it is recommended that clients migrate
* away from constructing non-conforming locales and use the
* forLanguageTag
and Locale.Builder
APIs instead.
* Clients desiring a string representation of the complete locale can
* then always rely on toLanguageTag
for this purpose.
*
*
Special cases
*
* For compatibility reasons, two
* non-conforming locales are treated as special cases. These are
* ja_JP_JP and th_TH_TH. These are ill-formed
* in BCP 47 since the variants are too short. To ease migration to BCP 47,
* these are treated specially during construction. These two cases (and only
* these) cause a constructor to generate an extension, all other values behave
* exactly as they did prior to Java 7.
*
*
Java has used ja_JP_JP to represent Japanese as used in
* Japan together with the Japanese Imperial calendar. This is now
* representable using a Unicode locale extension, by specifying the
* Unicode locale key ca (for "calendar") and type
* japanese. When the Locale constructor is called with the
* arguments "ja", "JP", "JP", the extension "u-ca-japanese" is
* automatically added.
*
*
Java has used th_TH_TH to represent Thai as used in
* Thailand together with Thai digits. This is also now representable using
* a Unicode locale extension, by specifying the Unicode locale key
* nu (for "number") and value thai. When the Locale
* constructor is called with the arguments "th", "TH", "TH", the
* extension "u-nu-thai" is automatically added.
*
*
Serialization
*
* During serialization, writeObject writes all fields to the output
* stream, including extensions.
*
*
During deserialization, readResolve adds extensions as described
* in Special Cases, only
* for the two cases th_TH_TH and ja_JP_JP.
*
*
Legacy language codes
*
* Locale's constructor has always converted three language codes to
* their earlier, obsoleted forms: he maps to iw,
* yi maps to ji, and id maps to
* in. This continues to be the case, in order to not break
* backwards compatibility.
*
*
The APIs added in 1.7 map between the old and new language codes,
* maintaining the old codes internal to Locale (so that
* getLanguage
and toString
reflect the old
* code), but using the new codes in the BCP 47 language tag APIs (so
* that toLanguageTag
reflects the new one). This
* preserves the equivalence between Locales no matter which code or
* API is used to construct them. Java's default resource bundle
* lookup mechanism also implements this mapping, so that resources
* can be named using either convention, see {@link ResourceBundle.Control}.
*
*
Three-letter language/country(region) codes
*
* The Locale constructors have always specified that the language
* and the country param be two characters in length, although in
* practice they have accepted any length. The specification has now
* been relaxed to allow language codes of two to eight characters and
* country (region) codes of two to three characters, and in
* particular, three-letter language codes and three-digit region
* codes as specified in the IANA Language Subtag Registry. For
* compatibility, the implementation still does not impose a length
* constraint.
*
* @see Builder
* @see ResourceBundle
* @see java.text.Format
* @see java.text.NumberFormat
* @see java.text.Collator
* @author Mark Davis
* @since 1.1
*/
public final class Locale implements Cloneable, Serializable {
/** Useful constant for language.
*/
static public final Locale ENGLISH = createConstant("en", "");
/** Useful constant for language.
*/
static public final Locale FRENCH = createConstant("fr", "");
/** Useful constant for language.
*/
static public final Locale GERMAN = createConstant("de", "");
/** Useful constant for language.
*/
static public final Locale ITALIAN = createConstant("it", "");
/** Useful constant for language.
*/
static public final Locale JAPANESE = createConstant("ja", "");
/** Useful constant for language.
*/
static public final Locale KOREAN = createConstant("ko", "");
/** Useful constant for language.
*/
static public final Locale CHINESE = createConstant("zh", "");
/** Useful constant for language.
*/
static public final Locale SIMPLIFIED_CHINESE = createConstant("zh", "CN");
/** Useful constant for language.
*/
static public final Locale TRADITIONAL_CHINESE = createConstant("zh", "TW");
/** Useful constant for country.
*/
static public final Locale FRANCE = createConstant("fr", "FR");
/** Useful constant for country.
*/
static public final Locale GERMANY = createConstant("de", "DE");
/** Useful constant for country.
*/
static public final Locale ITALY = createConstant("it", "IT");
/** Useful constant for country.
*/
static public final Locale JAPAN = createConstant("ja", "JP");
/** Useful constant for country.
*/
static public final Locale KOREA = createConstant("ko", "KR");
/** Useful constant for country.
*/
static public final Locale CHINA = SIMPLIFIED_CHINESE;
/** Useful constant for country.
*/
static public final Locale PRC = SIMPLIFIED_CHINESE;
/** Useful constant for country.
*/
static public final Locale TAIWAN = TRADITIONAL_CHINESE;
/** Useful constant for country.
*/
static public final Locale UK = createConstant("en", "GB");
/** Useful constant for country.
*/
static public final Locale US = createConstant("en", "US");
/** Useful constant for country.
*/
static public final Locale CANADA = createConstant("en", "CA");
/** Useful constant for country.
*/
static public final Locale CANADA_FRENCH = createConstant("fr", "CA");
/**
* Useful constant for the root locale. The root locale is the locale whose
* language, country, and variant are empty ("") strings. This is regarded
* as the base locale of all locales, and is used as the language/country
* neutral locale for the locale sensitive operations.
*
* @since 1.6
*/
static public final Locale ROOT = createConstant("", "");
/**
* The key for the private use extension ('x').
*
* @see #getExtension(char)
* @see Builder#setExtension(char, String)
* @since 1.7
*/
static public final char PRIVATE_USE_EXTENSION = 'x';
/**
* The key for Unicode locale extension ('u').
*
* @see #getExtension(char)
* @see Builder#setExtension(char, String)
* @since 1.7
*/
static public final char UNICODE_LOCALE_EXTENSION = 'u';
/** serialization ID
*/
static final long serialVersionUID = 9149081749638150636L;
/**
* Display types for retrieving localized names from the name providers.
*/
private static final int DISPLAY_LANGUAGE = 0;
private static final int DISPLAY_COUNTRY = 1;
private static final int DISPLAY_VARIANT = 2;
private static final int DISPLAY_SCRIPT = 3;
static Locale getInstance(String language, String script, String region, String v, Object object) {
return new Locale(language, script, region);
}
static Locale getInstance(String no, String no0, String ny) {
return new Locale(no, no0, ny);
}
private String language;
private String country;
private String variant;
/**
* Construct a locale from language, country and variant.
* This constructor normalizes the language value to lowercase and
* the country value to uppercase.
*
* Note:
*
* - ISO 639 is not a stable standard; some of the language codes it defines
* (specifically "iw", "ji", and "in") have changed. This constructor accepts both the
* old codes ("iw", "ji", and "in") and the new codes ("he", "yi", and "id"), but all other
* API on Locale will return only the OLD codes.
*
- For backward compatibility reasons, this constructor does not make
* any syntactic checks on the input.
*
- The two cases ("ja", "JP", "JP") and ("th", "TH", "TH") are handled specially,
* see Special Cases for more information.
*
*
* @param language An ISO 639 alpha-2 or alpha-3 language code, or a language subtag
* up to 8 characters in length. See the Locale
class description about
* valid language values.
* @param country An ISO 3166 alpha-2 country code or a UN M.49 numeric-3 area code.
* See the Locale
class description about valid country values.
* @param variant Any arbitrary value used to indicate a variation of a Locale
.
* See the Locale
class description for the details.
* @exception NullPointerException thrown if any argument is null.
*/
public Locale(String language, String country, String variant) {
if (language== null || country == null || variant == null) {
throw new NullPointerException();
}
this.language = language;
this.country = country;
this.variant = variant;
}
/**
* Construct a locale from language and country.
* This constructor normalizes the language value to lowercase and
* the country value to uppercase.
*
* Note:
*
* - ISO 639 is not a stable standard; some of the language codes it defines
* (specifically "iw", "ji", and "in") have changed. This constructor accepts both the
* old codes ("iw", "ji", and "in") and the new codes ("he", "yi", and "id"), but all other
* API on Locale will return only the OLD codes.
*
- For backward compatibility reasons, this constructor does not make
* any syntactic checks on the input.
*
*
* @param language An ISO 639 alpha-2 or alpha-3 language code, or a language subtag
* up to 8 characters in length. See the Locale
class description about
* valid language values.
* @param country An ISO 3166 alpha-2 country code or a UN M.49 numeric-3 area code.
* See the Locale
class description about valid country values.
* @exception NullPointerException thrown if either argument is null.
*/
public Locale(String language, String country) {
this(language, country, "");
}
/**
* Construct a locale from a language code.
* This constructor normalizes the language value to lowercase.
*
* Note:
*
* - ISO 639 is not a stable standard; some of the language codes it defines
* (specifically "iw", "ji", and "in") have changed. This constructor accepts both the
* old codes ("iw", "ji", and "in") and the new codes ("he", "yi", and "id"), but all other
* API on Locale will return only the OLD codes.
*
- For backward compatibility reasons, this constructor does not make
* any syntactic checks on the input.
*
*
* @param language An ISO 639 alpha-2 or alpha-3 language code, or a language subtag
* up to 8 characters in length. See the Locale
class description about
* valid language values.
* @exception NullPointerException thrown if argument is null.
* @since 1.4
*/
public Locale(String language) {
this(language, "", "");
}
/**
* This method must be called only for creating the Locale.*
* constants due to making shortcuts.
*/
private static Locale createConstant(String lang, String country) {
return new Locale(lang, country);
}
/**
* Gets the current value of the default locale for this instance
* of the Java Virtual Machine.
*
* The Java Virtual Machine sets the default locale during startup
* based on the host environment. It is used by many locale-sensitive
* methods if no locale is explicitly specified.
* It can be changed using the
* {@link #setDefault(java.util.Locale) setDefault} method.
*
* @return the default locale for this instance of the Java Virtual Machine
*/
public static Locale getDefault() {
String lang = language();
if (lang != null) {
String[] arr = lang.split("-");
return new Locale(arr[0], arr.length == 1 ? "" : arr[1]);
}
return Locale.US;
}
@JavaScriptBody(args = {}, body = ""
+ "if (typeof navigator === 'undefined') return null;\n"
+ "if (navigator.language) return navigator.language;\n"
+ "if (navigator.userLangage) return navigator.userLangage;\n"
+ "return null;\n"
)
private static native String language();
/**
* Gets the current value of the default locale for the specified Category
* for this instance of the Java Virtual Machine.
*
* The Java Virtual Machine sets the default locale during startup based
* on the host environment. It is used by many locale-sensitive methods
* if no locale is explicitly specified. It can be changed using the
* setDefault(Locale.Category, Locale) method.
*
* @param category - the specified category to get the default locale
* @throws NullPointerException - if category is null
* @return the default locale for the specified Category for this instance
* of the Java Virtual Machine
* @see #setDefault(Locale.Category, Locale)
* @since 1.7
*/
public static Locale getDefault(Locale.Category category) {
return getDefault();
}
/**
* Sets the default locale for this instance of the Java Virtual Machine.
* This does not affect the host locale.
*
* If there is a security manager, its checkPermission
* method is called with a PropertyPermission("user.language", "write")
* permission before the default locale is changed.
*
* The Java Virtual Machine sets the default locale during startup
* based on the host environment. It is used by many locale-sensitive
* methods if no locale is explicitly specified.
*
* Since changing the default locale may affect many different areas
* of functionality, this method should only be used if the caller
* is prepared to reinitialize locale-sensitive code running
* within the same Java Virtual Machine.
*
* By setting the default locale with this method, all of the default
* locales for each Category are also set to the specified default locale.
*
* @throws SecurityException
* if a security manager exists and its
* checkPermission
method doesn't allow the operation.
* @throws NullPointerException if newLocale
is null
* @param newLocale the new default locale
* @see SecurityManager#checkPermission
* @see java.util.PropertyPermission
*/
public static void setDefault(Locale newLocale) {
throw new SecurityException();
}
/**
* Returns an array of all installed locales.
* The returned array represents the union of locales supported
* by the Java runtime environment and by installed
* {@link java.util.spi.LocaleServiceProvider LocaleServiceProvider}
* implementations. It must contain at least a Locale
* instance equal to {@link java.util.Locale#US Locale.US}.
*
* @return An array of installed locales.
*/
public static Locale[] getAvailableLocales() {
return new Locale[] { Locale.US };
}
/**
* Returns the language code of this Locale.
*
*
Note: ISO 639 is not a stable standard— some languages' codes have changed.
* Locale's constructor recognizes both the new and the old codes for the languages
* whose codes have changed, but this function always returns the old code. If you
* want to check for a specific language whose code has changed, don't do
*
* if (locale.getLanguage().equals("he")) // BAD!
* ...
*
* Instead, do
*
* if (locale.getLanguage().equals(new Locale("he").getLanguage()))
* ...
*
* @return The language code, or the empty string if none is defined.
* @see #getDisplayLanguage
*/
public String getLanguage() {
return language;
}
/**
* Returns the script for this locale, which should
* either be the empty string or an ISO 15924 4-letter script
* code. The first letter is uppercase and the rest are
* lowercase, for example, 'Latn', 'Cyrl'.
*
* @return The script code, or the empty string if none is defined.
* @see #getDisplayScript
* @since 1.7
*/
public String getScript() {
return "";
}
/**
* Returns the country/region code for this locale, which should
* either be the empty string, an uppercase ISO 3166 2-letter code,
* or a UN M.49 3-digit code.
*
* @return The country/region code, or the empty string if none is defined.
* @see #getDisplayCountry
*/
public String getCountry() {
return country;
}
/**
* Returns the variant code for this locale.
*
* @return The variant code, or the empty string if none is defined.
* @see #getDisplayVariant
*/
public String getVariant() {
return variant;
}
String getRegion() {
return getCountry();
}
/**
* Returns the extension (or private use) value associated with
* the specified key, or null if there is no extension
* associated with the key. To be well-formed, the key must be one
* of [0-9A-Za-z]
. Keys are case-insensitive, so
* for example 'z' and 'Z' represent the same extension.
*
* @param key the extension key
* @return The extension, or null if this locale defines no
* extension for the specified key.
* @throws IllegalArgumentException if key is not well-formed
* @see #PRIVATE_USE_EXTENSION
* @see #UNICODE_LOCALE_EXTENSION
* @since 1.7
*/
public String getExtension(char key) {
return null;
}
/**
* Returns the set of extension keys associated with this locale, or the
* empty set if it has no extensions. The returned set is unmodifiable.
* The keys will all be lower-case.
*
* @return The set of extension keys, or the empty set if this locale has
* no extensions.
* @since 1.7
*/
public Set getExtensionKeys() {
return Collections.emptySet();
}
/**
* Returns the set of unicode locale attributes associated with
* this locale, or the empty set if it has no attributes. The
* returned set is unmodifiable.
*
* @return The set of attributes.
* @since 1.7
*/
public Set getUnicodeLocaleAttributes() {
return Collections.emptySet();
}
/**
* Returns the Unicode locale type associated with the specified Unicode locale key
* for this locale. Returns the empty string for keys that are defined with no type.
* Returns null if the key is not defined. Keys are case-insensitive. The key must
* be two alphanumeric characters ([0-9a-zA-Z]), or an IllegalArgumentException is
* thrown.
*
* @param key the Unicode locale key
* @return The Unicode locale type associated with the key, or null if the
* locale does not define the key.
* @throws IllegalArgumentException if the key is not well-formed
* @throws NullPointerException if key
is null
* @since 1.7
*/
public String getUnicodeLocaleType(String key) {
return null;
}
/**
* Returns the set of Unicode locale keys defined by this locale, or the empty set if
* this locale has none. The returned set is immutable. Keys are all lower case.
*
* @return The set of Unicode locale keys, or the empty set if this locale has
* no Unicode locale keywords.
* @since 1.7
*/
public Set getUnicodeLocaleKeys() {
return Collections.emptySet();
}
/**
* Returns a string representation of this Locale
* object, consisting of language, country, variant, script,
* and extensions as below:
*
* language + "_" + country + "_" + (variant + "_#" | "#") + script + "-" + extensions
*
*
* Language is always lower case, country is always upper case, script is always title
* case, and extensions are always lower case. Extensions and private use subtags
* will be in canonical order as explained in {@link #toLanguageTag}.
*
* When the locale has neither script nor extensions, the result is the same as in
* Java 6 and prior.
*
*
If both the language and country fields are missing, this function will return
* the empty string, even if the variant, script, or extensions field is present (you
* can't have a locale with just a variant, the variant must accompany a well-formed
* language or country code).
*
*
If script or extensions are present and variant is missing, no underscore is
* added before the "#".
*
*
This behavior is designed to support debugging and to be compatible with
* previous uses of toString
that expected language, country, and variant
* fields only. To represent a Locale as a String for interchange purposes, use
* {@link #toLanguageTag}.
*
*
Examples:
* - en
*
- de_DE
*
- _GB
*
- en_US_WIN
*
- de__POSIX
*
- zh_CN_#Hans
*
- zh_TW_#Hant-x-java
*
- th_TH_TH_#u-nu-thai
*
* @return A string representation of the Locale, for debugging.
* @see #getDisplayName
* @see #toLanguageTag
*/
@Override
public final String toString() {
Locale baseLocale = this;
boolean l = (baseLocale.getLanguage().length() != 0);
boolean s = (baseLocale.getScript().length() != 0);
boolean r = (baseLocale.getRegion().length() != 0);
boolean v = (baseLocale.getVariant().length() != 0);
boolean e = false; //(localeExtensions != null && localeExtensions.getID().length() != 0);
StringBuilder result = new StringBuilder(baseLocale.getLanguage());
if (r || (l && (v || s || e))) {
result.append('_')
.append(baseLocale.getRegion()); // This may just append '_'
}
if (v && (l || r)) {
result.append('_')
.append(baseLocale.getVariant());
}
if (s && (l || r)) {
result.append("_#")
.append(baseLocale.getScript());
}
if (e && (l || r)) {
result.append('_');
if (!s) {
result.append('#');
}
// result.append(localeExtensions.getID());
}
return result.toString();
}
/**
* Overrides Cloneable.
*/
public Object clone()
{
try {
Locale that = (Locale)super.clone();
return that;
} catch (CloneNotSupportedException e) {
throw new InternalError();
}
}
/**
* Override hashCode.
* Since Locales are often used in hashtables, caches the value
* for speed.
*/
@Override
public int hashCode() {
int hash = 3;
hash = 43 * hash + Objects.hashCode(this.language);
hash = 43 * hash + Objects.hashCode(this.country);
hash = 43 * hash + Objects.hashCode(this.variant);
return hash;
}
// Overrides
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Locale other = (Locale) obj;
if (!Objects.equals(this.language, other.language)) {
return false;
}
if (!Objects.equals(this.country, other.country)) {
return false;
}
if (!Objects.equals(this.variant, other.variant)) {
return false;
}
return true;
}
/**
* Enum for locale categories. These locale categories are used to get/set
* the default locale for the specific functionality represented by the
* category.
*
* @see #getDefault(Locale.Category)
* @see #setDefault(Locale.Category, Locale)
* @since 1.7
*/
public enum Category {
/**
* Category used to represent the default locale for
* displaying user interfaces.
*/
DISPLAY("user.language.display",
"user.script.display",
"user.country.display",
"user.variant.display"),
/**
* Category used to represent the default locale for
* formatting dates, numbers, and/or currencies.
*/
FORMAT("user.language.format",
"user.script.format",
"user.country.format",
"user.variant.format");
Category(String languageKey, String scriptKey, String countryKey, String variantKey) {
this.languageKey = languageKey;
this.scriptKey = scriptKey;
this.countryKey = countryKey;
this.variantKey = variantKey;
}
final String languageKey;
final String scriptKey;
final String countryKey;
final String variantKey;
}
}