國際化 ,英文叫 internationalization 單詞太長 ,又被簡稱爲 i18n(取頭取尾中間有18個字母)不經大聲呼喊 ,這都行 !接着看什麼是國際化 , 國際化是指讓產品或是程序在無需作出改變的狀況下就可以適應不一樣語言和地區的須要 。一樣是打招呼在中國你會說 「 你好 」 ,在美國你會說 「 Hello 」 ,你看 ,你已是 i18n 了 。java
在 Java 中實現國際化主要是藉助一個工具類 ResourceBundle ,核心的思想就是 ,對不一樣的語言環境提供一個不一樣的資源文件 。因此說先來看看資源文件怎麼定義的 。數組
定義相應的資源文件 ,咱們將資源文件放在一個資源包(就是日常的一個包)中 ,一個資源包中每一個資源文件必須擁有共同的基名 。除了基名 ,每一個文件的名稱中還必須有標識其本地信息的附加部分 ,例如 :一個資源包的基名是 「 message 」 ,則與中文(中國)、英文(美國)環境相對應的資源文件名分別爲 :
message_zh_CN.properties
message_en_US.properties工具
這裏須要注意的是 ,資源文件一般採用鍵值對的形式 ,而且資源文件中採用的是 properties 格式文件 ,因此文件中的全部字符都必須是 ascll 碼 ,不能保存爲中文的 ,Java 中提供 了 native2ascll 工具用於將中文轉化爲 ascll 碼 。因此在編寫 properties 文件的時候寫的是中文 ,一回車就自動被編碼了 。測試
下面就是具體的編碼了 ,在 Java API 中提供了一個 ResourceBundle 類用於描述一個資源包 ,而且 ResourceBundle 類提供了相應的靜態方法 getBundle ,這個方法能夠根據來訪者的國家地區自動綁定對應的資源文件 。ui
import java.util.Locale; import java.util.ResourceBundle; public class I18n{ public static void test() { // 設置定製的語言國家代碼 Locale locale1 = new Locale("en_US"); Locale locale2 = Locale.getDefault(); // 得到資源文件 ResourceBundle rb = ResourceBundle.getBundle("message.i18n.message", locale2); // 得到相應的key值 String greeting = rb.getString("greeting"); String userInfo = rb.getString("name"); System.out.println(greeting); System.out.println(userInfo); } public static void main(String[] args) { test(); } } //你好 //餘6路
以上就是一些固定文本的國際化 ,固定文本包括菜單名 ,導航條 ,系統提示信息等 ,都是咱們手工配置在 properties 文件中的 ,但有些數據 ,比方說 ,數值 ,貨幣 ,時間 ,日期等因爲可能在程序運行時動態產生 ,因此沒法像文字同樣簡單地將它們從應用程序中分離出來 ,而須要特殊處理 。Java 提供瞭解決這些問題的 API 。編碼
簡單的說一下 Locale 這個類 ,英語介紹是這樣的spa
A Locale object represents a specific geographical , political , or cultural region . An operation that requires a Locale to perform its task is called locale-sensitive and uses the Locale to tailor information for the user .翻譯
翻譯過來就是說 Locate 對象表明特定的地理 ,政治或文化區域 。須要 Locate 設置執行任務的操做稱爲敏感區域( 包含 Locate 的類就是敏感區域 ) ,使用 Locate 爲用戶定製信息 。code
關於日期的國際化咱們使用工具類 DateFormat ,看一下該類的結構圖 。orm
DateFormat 有不少不一樣的構造器 ,並且在構造器中還能夠指定不一樣的時間顯示模式 ,我就不一一演示了 ,下面給出示例代碼 。
public class DateFormatTest { public static void main(String[] args) throws ParseException { Date date = new Date(); DateFormat df = DateFormat.getDateInstance(DateFormat.DEFAULT, Locale.CHINA); String str = df.format(date); System.out.println(str); // 2018-8-6 df = DateFormat.getTimeInstance(DateFormat.LONG, Locale.CHINA); System.out.println(df.format(date)); // 下午07時58分26秒 df = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.SHORT, Locale.CHINA); System.out.println(df.format(date)); // 2018年8月6日 星期一 下午7:58 // 獲得默認的DateFormat df = DateFormat.getInstance(); System.out.println(df.format(date)); // 18-8-6 下午7:58 // 使用DateFormat反向把一個字符串格式化成一個日期對象 String dateString = "2018年8月6日 星期一 下午7:58"; DateFormat df2 = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.SHORT, Locale.CHINA); Date date2 = df2.parse(dateString); // 這裏可能會有異常,字符串的格式和 DateFormat 設置的格式不一致時就會報錯。 System.out.println(date2); // Mon Aug 06 19:58:00 CST 2018 } }
動態文本國際化使用工具類 MessageFormat ,MessageFormat 容許開發人員用佔位符替換掉字符串中的敏感數據( 即國際化相關的數據 )字符串中的 {0} {1} {2} {3} 就是佔位符 。
public class MessageFormatTest { public static void main(String[] args) { /* 測試數據 greeting=Welcome name=YJK age=18 pattern={0},{1},your age is {2}. */ ResourceBundle rb = ResourceBundle.getBundle("message.i18n.message_en_US",Locale.US); String greeting = rb.getString("greeting"); String name = rb.getString("name"); String age = rb.getString("age"); // 獲得模式字符串 String pattern = rb.getString("message"); // 實例化MessageFormat對象,並裝載相應的模式字符串 MessageFormat format = new MessageFormat(pattern); // format 方法須要一個 Object 的數組。 Object[] params = {greeting, name, age}; // 格式化模式字符串,參數數組中指定佔位符相應的替換對象 String string = format.format(params); System.out.println(string); } } //Welcome,YJK,your age is 18.
NumberFormat 類能夠將一個數值格式化爲符合某個國家地區習慣的數值字符串 ,也能夠將符合某個國家地區習慣的數值字符串解析爲對應的數值 。 對應的方法分別是 format 和 parse 。
public class NumberFormatTest { public static void main(String[] args) throws ParseException{ int price = 18; // NumberFormat nf = NumberFormat.getCurrencyInstance(Locale.CHINA); // ¥18.00 // NumberFormat nf = NumberFormat.getCurrencyInstance(Locale.US); // $18.00 // NumberFormat nf = NumberFormat.getCurrencyInstance(Locale.JAPAN); // ¥18 // 得到處理貨幣的 NumberFormat 實例對象 NumberFormat nf = NumberFormat.getCurrencyInstance(Locale.FRANCE); // 18,00 € System.out.println(nf.format(price)); String s = "18,00 €"; nf = NumberFormat.getCurrencyInstance(Locale.FRANCE); // 以法國的貨幣來解析 18,00 € 獲得的結果是 18.0 System.out.println(nf.parse(s).doubleValue()); double d = 0.1; // 得到處理整數的NumberFormat實例對象。 nf = NumberFormat.getIntegerInstance(); // 0 // 得到處理百分比數值的 NumberFormat 實例對象 nf = NumberFormat.getPercentInstance(); System.out.println(nf.format(d)); // 10% } }