Internationalization (a.k.a i18n)
Table of contents
需要被多國語系的內容有
- 數字
- 貨幣金額
- 日期
- 時間
- 文字
檔名格式
- MessagesBundle_en_US.properties
- MessagesBundle_fr_FR.properties
- MessagesBundle_de_DE.properties
- MessagesBundle_zh_TW.properties
- MessagesBundle_zh_CN.properties
MessagesBundle可換成適合的檔名.Language(小寫)跟Country(大寫)用底線(“_”)分隔。
取得有效的語系
DateFormat.getAvailableLocales();
// result
ar_EG
be_BY
bg_BG
ca_ES
cs_CZ
da_DK
de_DE
.
.
.
Locale.getDisplayName
// result
Arabic (Egypt)
Belarussian (Belarus)
Bulgarian (Bulgaria)
Catalan (Spain)
Czech (Czech Republic)
Danish (Denmark)
German (Germany)
ResourceBundle尋找順序
指定語系是fr,國家是CA,而且是在LINUX作業系統,系統會依下列順序尋找ResourceBundle
- ButtonLabel_fr_CA_UNIX
- ButtonLabel_fr_CA
- ButtonLabel_fr
- ButtonLabel_en_US
- ButtonLabel_en
- ButtonLabel
客制ResourceBundle載入邏輯
透過java.util.ResourceBundle.Control
可以自訂ResourceBundle載入的邏輯
ResourceBundle rb = ResourceBundle.getBundle("RBControl", locale,
new ResourceBundle.Control() {
@Override
public List<Locale> getCandidateLocales(String baseName, Locale locale) {
if (baseName == null)
throw new NullPointerException();
if (locale.equals(new Locale("zh", "HK"))) {
return Arrays.asList(
locale,
Locale.TAIWAN,
// no Locale.CHINESE here
Locale.ROOT);
} else if (locale.equals(Locale.TAIWAN)) {
return Arrays.asList(
locale,
// no Locale.CHINESE here
Locale.ROOT);
}
return super.getCandidateLocales(baseName, locale);
}
});
Messages
如果是字串裡包含著會變數(會變動的內容 ex: “hi username, how are you today?”這是一整段字串,但其中的username會需被置換成使用者的姓名),需多做額外的處理。
格式化
- 數字(含金額跟貨幣符號 €,¥以及%等符號)
- 日期
- DateFormat
- SimpleDateFormat
- DateFormatSymbols
- 封裝了日期時間相關的符號,像Mon,PM/AM,…
- 一般文字
字串裏面包含多種形態的變數,顯示日期,時間,貨幣等,可用Message Pattern的方式來處理
ex:
"Hi {0}!, today is {1,date,short}" {0}會代入"Kent", {1}代入new Date()後會的到像這樣的輸出
Hi, Kent! Today is 2010/12/7
利用這種方式,可以把格式化的行為延遲到RUNTIME.
單/複數問題
有些語言,像是拉丁英系,名詞會有單複數之分(ex: 英文 a apple,two apples),處理這類的問題時,或許可以參考一下這裡