java.util.Locale возвращает другой язык, на котором он построен - PullRequest
0 голосов
/ 16 мая 2018

Рассмотрим простой тест, который я написал на 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)
    }
}

Второй тест не пройден, поскольку ожидается, что он будет id, но на самом деле in.Как это возможно?Locale был построен с языком id, разве не стоит с уверенностью предполагать, что он вернет тот же язык?

Ответы [ 4 ]

0 голосов
/ 16 мая 2018

Из Javadoc :

Примечание: ISO 639 не является стабильным стандартом - коды некоторых языков изменились.Конструктор локали распознает как новые, так и старые коды для языков, коды которых изменились, но эта функция всегда возвращает старый код.

Если вы хотите проверить конкретный язык, код которого изменился,не делай

 if (locale.getLanguage().equals("he")) // BAD!

Вместо этого делай

if (locale.getLanguage().equals(new Locale("he").getLanguage()))
0 голосов
/ 16 мая 2018

В документации по java.util.Locale getLanguage() говорится следующее:

public String getLanguage ()

Возвращает код языка этой локали.

Примечание: ISO 639 не является стабильным стандартом - коды некоторых языков изменились. Конструктор Locale распознает как новые, так и старые коды для языков, коды которых изменились, но эта функция всегда возвращает старый код. Если вы хотите проверить конкретный язык, код которого изменился, не делайте

Источник: https://docs.oracle.com/javase/7/docs/api/java/util/Locale.html#getLanguage()

Это означает, что в определенный момент времени в соответствии со стандартом ISO 639 индонезийский языковой стандарт был обозначен in, однако с тех пор произошли изменения, в результате которых идентификатор индонезийского языкового стандарта изменился на id.

0 голосов
/ 16 мая 2018

Это известная ошибка в Java, которая не будет исправлена ​​для обеспечения обратной совместимости.

Для получения дополнительной информации: https://bugs.java.com/view_bug.do?bug_id=6457127

0 голосов
/ 16 мая 2018

Из документации:

ISO 639 не является стабильным стандартом;некоторые коды языков, которые он определяет * (в частности, «iw», «ji» и «in»), изменились.Этот конструктор принимает как * старые коды ("iw", "ji" и "in"), так и новые коды ("he", "yi" и "id"), но все остальные * API в Locale будут возвращатьтолько СТАРЫЕ коды.

Так что id является новым, однако в документации конкретно сказано, что для этого случая будет возвращено in.Это почему?Я полагаю, возможно, не стоит ломать старые приложения, используя in как ожидаемый результат, другими словами, для поддержки обратной совместимости.

Если вам нужно проверить, является ли locale, который вы используете, индонезийским, то рекомендуетсявероятно, было бы создать некоторую статическую константную переменную с указанным языковым стандартом и проверить равенство с ней.

Так что в некотором классе Util (в Kotlin вы можете использовать вместо него объект-компаньон):

public static final Locale INDONESIAN_LOCALE = new Locale("id");

и когда вам нужно проверить:

if (INDONESIAN_LOCALE.equals(receivedLocale)) {
     ...they are the same...
}
...