Reputation: 5858
Consider a simple test I've written in Kotlin:
class LocaleTest {
@Test fun english() {
val locale = Locale("en")
assertEquals("English", locale.displayLanguage)
assertEquals("en", locale.language)
}
@Test fun indonesia() {
val locale = Locale("id")
assertEquals("Indonesian", locale.displayLanguage)
assertEquals("id", locale.language)
}
}
The second test fails because it is expected to be id
but actually in
. How is this possible? The Locale
was built with language id
, shouldn't it be safe to assume that it will return the same language?
Upvotes: 6
Views: 2119
Reputation: 2216
From the documentation:
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.
So id
is a new one, however documentation specifically says that for this case in
would be returned.
Why is that? I believe, may be not to break old applications using in
as expected output, so in other words to support backwards compatibility.
If you need to check if locale
you are using is Indonesian then recommended way would probably be to create some static constant variable with specified locale, and to check equality with it.
So in some Util class(in Kotlin you can use companion object instead I think):
public static final Locale INDONESIAN_LOCALE = new Locale("id");
and when you need to check:
if (INDONESIAN_LOCALE.equals(receivedLocale)) {
...they are the same...
}
Upvotes: 2
Reputation: 14999
From the Javadoc:
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()))
Upvotes: 3
Reputation: 5072
This is a known bug in Java that won't be fixed in order to maintain backwards-compatibility.
For more info: https://bugs.java.com/view_bug.do?bug_id=6457127
Upvotes: 1
Reputation: 5747
A look at the documentation for java.util.Locale
's getLanguage()
says the following:
public String getLanguage()
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
Source: https://docs.oracle.com/javase/7/docs/api/java/util/Locale.html#getLanguage()
What this means is that at one point in time according to the ISO 639 standard, the Indonesian Locale was identified by in
, however there have been changes since then which had the Indonesian Locale identifier change to id
.
Upvotes: 2