Android 上的 toUpperCase 对于 two-argument 和默认的希腊语和土耳其语区域设置不正确
toUpperCase on Android is incorrect for two-argument and default Greek and Turkish Locales
在默认语言环境下使用 toUpperCase() 或更有趣的是两个参数 Locale 构造函数时,我在使用希腊语和土耳其语时遇到问题。
问题发生在 Galaxy Tab S2 Android 5.0.2(也在 5.1.1 上重现)
该问题可通过设置应用程序和 MoreLocale 2 重现
考虑标题的这个值:Τέλος συνεδρίας
这些调用工作正常。
title.toUpperCase(new Locale("el_GR"))
title.toUpperCase(new Locale("el-GR"))
两者都产生了正确的结果。如果你仔细看,在 T 和 P 之后有刻度线。
ΤΈΛΟΣ ΣΥΝΕΔΡΙΑΣ
但是,对于默认语言环境和 two-argument 语言环境构造函数,我得到了不同的结果。
这是我平板电脑上的默认语言环境:
Locale.getDefault() == el_GR
在泛型 toUpperCase() 中使用
public String toUpperCase() {
return CaseMapper.toUpperCase(Locale.getDefault(), this, value, offset, count);
}
当我称它时 returns 结果不正确。
title.toUpperCase()
注意 T 和 P 上缺少的刻度线。
ΤΕΛΟΣ ΣΥΝΕΔΡΙΑΣ
如果我对新语言环境使用双参数构造函数,我会得到相同的结果:
title.toUpperCase(new Locale("el","GR"))
ΤΕΛΟΣ ΣΥΝΕΔΡΙΑΣ
将这些行添加到应用程序启动中可以解决问题,但有点老套。
String language = Locale.getDefault().getLanguage();
String country = Locale.getDefault().getCountry();
Locale.setDefault(new Locale(language + "-" + country));
我宁愿简单地遵从默认语言环境。
正如您在 CaseMapper.java 中看到的那样,方法 toUpperCase
对阿塞拜疆语、立陶宛语、土耳其语和希腊语语言环境有特殊的行为:
public static String toUpperCase(Locale locale, String s, int count) {
String languageCode = locale.getLanguage();
if (languageCode.equals("tr") || languageCode.equals("az") || languageCode.equals("lt")) {
return ICU.toUpperCase(s, locale);
}
if (languageCode.equals("el")) {
return EL_UPPER.get().transliterate(s);
}
...
}
为什么根据使用的 Locale
类型会得到不同的结果?
让我们尝试分析创建的 Locale
的不同类型:
locale = new Locale("el_GR");
Log.d(TAG, String.format("[el_GR] Language: '%s' ~ Country: '%s'", locale.getLanguage(), locale.getCountry()));
locale = new Locale("el", "GR");
Log.d(TAG, String.format("[el, GR] Language: '%s' ~ Country: '%s'", locale.getLanguage(), locale.getCountry()));
locale = Locale.getDefault(); //Device with el_GR language
Log.d(TAG, String.format("[default] Language: '%s' ~ Country: '%s'", locale.getLanguage(), locale.getCountry()));
获得的结果如下:
[el_GR] Language: 'el_gr' ~ Country: ''
[el, GR] Language: 'el' ~ Country: 'GR'
[default] Language: 'el' ~ Country: 'GR'
正如您在手动创建的 Locale
中看到的那样,只有一个参数的语言是 el_gr
,而对于其他两种情况,语言是 el
。 toUpperCase
只有当语言代码为 tr
、az
、lt
或 el
时才会有不同的行为,否则它会正常行为。由于这个原因,输出是不同的。
不幸的是,如果你想要刻度线,唯一可行的解决方案是使用只有一个参数的 Locale
构造函数。
在默认语言环境下使用 toUpperCase() 或更有趣的是两个参数 Locale 构造函数时,我在使用希腊语和土耳其语时遇到问题。
问题发生在 Galaxy Tab S2 Android 5.0.2(也在 5.1.1 上重现)
该问题可通过设置应用程序和 MoreLocale 2 重现
考虑标题的这个值:Τέλος συνεδρίας
这些调用工作正常。
title.toUpperCase(new Locale("el_GR"))
title.toUpperCase(new Locale("el-GR"))
两者都产生了正确的结果。如果你仔细看,在 T 和 P 之后有刻度线。
ΤΈΛΟΣ ΣΥΝΕΔΡΙΑΣ
但是,对于默认语言环境和 two-argument 语言环境构造函数,我得到了不同的结果。
这是我平板电脑上的默认语言环境:
Locale.getDefault() == el_GR
在泛型 toUpperCase() 中使用
public String toUpperCase() {
return CaseMapper.toUpperCase(Locale.getDefault(), this, value, offset, count);
}
当我称它时 returns 结果不正确。
title.toUpperCase()
注意 T 和 P 上缺少的刻度线。
ΤΕΛΟΣ ΣΥΝΕΔΡΙΑΣ
如果我对新语言环境使用双参数构造函数,我会得到相同的结果:
title.toUpperCase(new Locale("el","GR"))
ΤΕΛΟΣ ΣΥΝΕΔΡΙΑΣ
将这些行添加到应用程序启动中可以解决问题,但有点老套。
String language = Locale.getDefault().getLanguage();
String country = Locale.getDefault().getCountry();
Locale.setDefault(new Locale(language + "-" + country));
我宁愿简单地遵从默认语言环境。
正如您在 CaseMapper.java 中看到的那样,方法 toUpperCase
对阿塞拜疆语、立陶宛语、土耳其语和希腊语语言环境有特殊的行为:
public static String toUpperCase(Locale locale, String s, int count) {
String languageCode = locale.getLanguage();
if (languageCode.equals("tr") || languageCode.equals("az") || languageCode.equals("lt")) {
return ICU.toUpperCase(s, locale);
}
if (languageCode.equals("el")) {
return EL_UPPER.get().transliterate(s);
}
...
}
为什么根据使用的 Locale
类型会得到不同的结果?
让我们尝试分析创建的 Locale
的不同类型:
locale = new Locale("el_GR");
Log.d(TAG, String.format("[el_GR] Language: '%s' ~ Country: '%s'", locale.getLanguage(), locale.getCountry()));
locale = new Locale("el", "GR");
Log.d(TAG, String.format("[el, GR] Language: '%s' ~ Country: '%s'", locale.getLanguage(), locale.getCountry()));
locale = Locale.getDefault(); //Device with el_GR language
Log.d(TAG, String.format("[default] Language: '%s' ~ Country: '%s'", locale.getLanguage(), locale.getCountry()));
获得的结果如下:
[el_GR] Language: 'el_gr' ~ Country: ''
[el, GR] Language: 'el' ~ Country: 'GR'
[default] Language: 'el' ~ Country: 'GR'
正如您在手动创建的 Locale
中看到的那样,只有一个参数的语言是 el_gr
,而对于其他两种情况,语言是 el
。 toUpperCase
只有当语言代码为 tr
、az
、lt
或 el
时才会有不同的行为,否则它会正常行为。由于这个原因,输出是不同的。
不幸的是,如果你想要刻度线,唯一可行的解决方案是使用只有一个参数的 Locale
构造函数。