Search code examples
javalocale

java.util.Locale returns different language it is built with


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?


Solution

  • 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.