1、國際化開發概述
(1)軟件的國際化:軟件開發時,要使它能同時應對世界不同地區和國家的訪問,並針對不同地區和國家的訪問,提供相應的、符合來訪者閱讀習慣的頁面或數據。
(2)國際化又稱爲 i18n:internationalization
2、合格的國際化軟件
軟件實現國際化,需具備哪些特徵:
(1)對於程序(頁面)中固定使用的文本元素,例如菜單欄、導航條等中使用的文本元素、或錯誤提示信息,狀態信息等,需要根據來訪者的地區和國家,選擇不同語言的文本爲之服務。
(2)對於程序動態產生的數據,例如(日期,貨幣等),軟件應能根據當前所在的國家或地區的文化習慣進行顯示。
3、固定文本元素的國際化
(1)對於軟件中的菜單欄、導航條、錯誤提示信息,狀態信息等這些固定不變的文本信息,可以把它們寫在一個properties文件中,並根據不同的國家編寫不同的properties文件。這一組properties文件稱之爲一個資源包。
(2)在JavaAPI中提供了一個ResourceBundle 類用於描述一個資源包,並且 ResourceBundle類提供了相應的方法getBundle,這個方法可以根據來訪者的國家地區自動獲取與之對應的資源文件予以顯示。
package com.itheima.i18n;
import java.util.Locale;
import java.util.ResourceBundle;
public class Demo1 {
public static void main(String[] args) {
ResourceBundle bundle = ResourceBundle.getBundle("conf",Locale.US);
String value = bundle.getString("username");
System.out.println(value);
}
}
4、創建資源包和資源文件
(1)一個資源包中的每個資源文件都必須擁有共同的basename基名。除了基名,每個資源文件的名稱中還必須有標識其本地信息的附加部分。例如:一個資源包的基名是“myproperties”,則與中文、英文環境相對應的資源文件名則爲:
“myproperites_zh.properties” “myproperites_en.properties”
(2)每個資源包都應有一個默認資源文件,這個文件不帶有標識本地信息的附加部分。若ResourceBundle對象在資源包中找不到與用戶匹配的資源文件,它將選擇該資源包中與用戶最相近的資源文件,如果再找不到,則使用默認資源文件。例如:
Myproperites.properties
5、語言和國別代碼
6、資源文件的書寫格式
(1)資源文件的內容通常採用“關鍵字=值”的形式,軟件根據關鍵字檢索值顯示在頁面上。一個資源包中的所有資源文件的關鍵字必須相同,值則爲相應國家的文字。
(2)並且資源文件中採用的是properties格式文件,所以文件中的所有字符都必須是ASCII字碼,對於像中文這樣的非ACSII字符,須先進行編碼。(java提供了一個native2ascII命令用於編碼)。例:
屬性文件是不能保存中文的
7、編程實現固定文本的國際化
(1)加載src下properties文件
ResourceBundle bundle = ResourceBundle.getBundle(basename);
(2)讀取properties文件中內容
String value = bundle.getString(key);
(3)在讀取properties文件時,可以傳入一個Locale 實例對象,用於代表一個特定的地理,政治、文化區域
ResourceBundle bundle =
ResourceBundle.getBundle(basename, currentLocale);
(4)如果與該locale對象匹配的資源包子類找不到。一般情況下,則選用操作系統默認資源文件予以顯示
(5)如果與該locale對象匹配的資源包子類找不到。一般情況下,則選用操作系統默認資源文件予以顯示
(6)案例:製作國際化登陸頁面
ResourceBundle bundle = ResourceBundle.getBundle("test", new Locale("ar"));
String prop = bundle.getString("prop1");
System.out.println(prop);
<fmt:setLocale value='en'/>
<fmt:setBundle basename="test" scope="page" var="t"/>
<fmt:message key="prop1" bundle="${t}"></fmt:message>
8、DateFormat類(國際化日期)
(1)DateFormat 類可以將一個日期/時間對象格式化爲表示某個國家地區的日期/時間字符串。
(2)DateFormat 類除了可按國家地區格式化輸出日期外,它還定義了一些用於描述日期/時間的顯示模式的 int 型的常量,包括FULL, LONG, MEDIUM, DEFAULT, SHORT,實例化DateFormat對象時,可以使用這些常量,控制日期/時間的顯示長度。
(3)Date date = new Date();
// 只需要顯示 日期
// style 就可以 FULL LONG MEDIUM SHORT
DateFormat df1 = DateFormat.getDateInstance(DateFormat.FULL,
Locale.CHINA);
System.out.println(df1.format(date));
// 只需要顯示時間
DateFormat df2 = DateFormat.getTimeInstance(DateFormat.LONG,
Locale.CANADA);
System.out.println(df2.format(date));
// 既需要日期也需要時間
DateFormat df3 = DateFormat.getDateTimeInstance(DateFormat.FULL,
DateFormat.FULL, Locale.GERMAN);
System.out.println(df3.format(date));
9、實例化DateFormat類
實例化DateFormat類有九種方式,以下三種爲帶參形式,下面列出的三種方式也可以分別不帶參,或只帶顯示樣式的參數。
(1)getDateInstance(int style, Locale aLocale):以指定的日期顯示模式和本地信息來獲得DateFormat實例對象,該實例對象不處理時間值部分。
(2)getTimeInstance(int style, Locale aLocale):以指定的時間顯示模式和本地信息來獲得DateFormat實例對象,該實例對象不處理日期值部分。
(3)getDateTimeInstance(int dateStyle, int timeStyle, Locale aLocale):以單獨指定的日期顯示模式、時間顯示模式和本地信息來獲得DateFormat實例對象。
package com.itheima.i18n;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import org.junit.Test;
public class DataFormatTest {
@Test
//將Date對象轉換爲指定樣式指定語言環境的字符串時間表示形式
public void test1(){
Date date = new Date();
DateFormat format = DateFormat.getDateTimeInstance(DateFormat.FULL,DateFormat.FULL, Locale.CHINA);
String dateStr = format.format(date);
System.out.println(dateStr);
}
//2013年7月27日 星期六 下午03時57分45秒 CST
@Test
public void test2() throws ParseException{
String dateStr = "2013年7月27日 星期六 下午03時57分45秒 CST";
DateFormat format = DateFormat.getDateTimeInstance(DateFormat.FULL,DateFormat.FULL,Locale.CHINA);
Date date = format.parse(dateStr);
System.out.println(date);
}
@Test
public void test3() throws ParseException{
String dateStr = "2013~~~09@@@@09,16?00+00";
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy~~~MM@@@@dd,HH?mm+ss");
Date date = dateFormat.parse(dateStr);
System.out.println(date);
}
@Test
public void test4(){
Date date = new Date();
SimpleDateFormat dateFormat = new SimpleDateFormat("MM~~~yyyy~~~~dd:mm~~~ss+HH");
String dateStr = dateFormat.format(date);
System.out.println(dateStr);
}
}
10、NumberFormat類
(1)實例化NumberFormat類時,可以使用locale對象作爲參數,也可以不使用,下面列出的是使用參數的。
(2)getNumberInstance(Locale locale):以參數locale對象所標識的本地信息來獲得具有多種用途的NumberFormat實例對象
(3)getIntegerInstance(Locale locale):以參數locale對象所標識的本地信息來獲得處理整數的NumberFormat實例對象
(4)getCurrencyInstance(Locale locale):以參數locale對象所標識的本地信息來獲得處理貨幣的NumberFormat實例對象
(5)getPercentInstance(Locale locale):以參數locale對象所標識的本地信息來獲得處理百分比數值的NumberFormat實例對象
public void demo4() {
// 請將0.78654321,輸出百分比格式,保留兩位小數
double d = 0.78654321;
double d2 = 0.543;
NumberFormat numberFormat = NumberFormat.getPercentInstance();
numberFormat.setMaximumFractionDigits(2);
numberFormat.setMinimumFractionDigits(2);
System.out.println(numberFormat.format(d));
System.out.println(numberFormat.format(d2));
}
public void demo3() throws ParseException {
// 請將整數198,輸出爲貨幣形式:$198,並將¥198反向解析成整數198。
int n = 198; // 輸出美元
NumberFormat format1 = NumberFormat.getCurrencyInstance(Locale.US);
format1.setMaximumFractionDigits(0);// 不要小數
System.out.println(format1.format(n));
String s = "¥198";
NumberFormat format2 = NumberFormat.getCurrencyInstance(Locale.CHINA);
Number m = format2.parse(s);
System.out.println(m);
}
package com.itheima.i18n;
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.Locale;
import org.junit.Test;
public class NumberFormatTest {
//100 ---> ¥100
@Test
public void test1(){
double num = 100.00;
NumberFormat format = NumberFormat.getCurrencyInstance(Locale.US);
String str = format.format(num);
System.out.println(str);
}
//¥100.00 -- > 100.00
@Test
public void test2() throws ParseException{
String str = "¥100.00";
NumberFormat format = NumberFormat.getCurrencyInstance(Locale.CHINA);
double num = format.parse(str).doubleValue();
System.out.println(num);
}
//99.1% --0.991
@Test
public void test3() throws ParseException{
String str = "99.1%";
NumberFormat format = NumberFormat.getPercentInstance(Locale.CHINA);
double num = format.parse(str).doubleValue();
System.out.println(num);
}
//0.8812 ---> 88.12%
@Test
public void test4(){
double num = 0.8812;
NumberFormat format = NumberFormat.getPercentInstance(Locale.GERMAN);
format.setMinimumFractionDigits(3);
String str = format.format(num);
System.out.println(str);
}
}
11、MessageFormat(動態文本)
(1)如果一個字符串中包含了多個與國際化相關的數據,可以使用MessageFormat類對這些數據進行批量處理。
(2)例如:
At 12:30 pm on jul 3,1998, a hurricance destroyed 99 houses and caused $1000000 of damage
以上字符串中包含了時間、數字、貨幣等多個與國際化相關的數據,對於這種字符串,可以使用MessageFormat類對其國際化相關的數據進行批量處理。
(3)MessageFormat 類如何進行批量處理呢?
1.MessageFormat類允許開發人員用佔位符{0}{1}{2}…替換掉字符串中的敏感數據(即國際化相關的數據)。
2.MessageFormat類在格式化輸出包含佔位符的文本時,messageFormat類可以接收一個參數數組,以替換文本中的每一個佔位符。
12、格式化模式字符串
(1)模式字符串:
On {0}, a hurricance destroyed {1} houses and caused {2} of damage.
(2)MessageFormat類
默認Locale
format(String pattern, Object... arguments) static
pattern 模式字符串
arguments 參數數組
自定義Locale
MessageFormat(String pattern, Locale locale)
format(Object obj)
String s = "At {0} on {1}, a hurricance destroyed {2} houses and caused {3} of damage";
Object[] args = { "12:30 pm", "jul 3,1998", "99", "$1000000" };
System.out.println(MessageFormat.format(s, args));
13、模式字符串與佔位符
位符有三種方式書寫方式:
(1){argumentIndex}: 0-9 之間的數字,表示要格式化對象數據在參數數組中的索引號
(2){argumentIndex,formatType}: 參數的格式化類型
(3){argumentIndex,formatType,FormatStyle}: 格式化的樣式,它的值必須是與格式化類型相匹配的合法模式、或表示合法模式的字符串。
formatType:
number
date
time
choice
fomatStyle
short
medium
long
full
integer
currency
percent
Subformatpattern
String pattern = "At {0,time,short} on {0,date,medium},a destroyed {1}
houses and caused {2,number,currency} of damage."
Calendar calendar = Calendar.getInstance();
calendar.set(1998, 6, 3, 12, 30, 0);
Date date = calendar.getTime();
Object []msgArgs = {date, 99, 1000000};
String result = MessageFormat.format(pattern,msgArgs); // 默認國家
System.out.println(result);
// 動態文本高級應用
String s = "At {0,time,short} on {0,date,medium}, a hurricance destroyed {1,number,integer} houses and caused {2,number,currency} of damage";
// 第一個參數 日期對象12:30 pm on jul 3,1998
Calendar calendar = Calendar.getInstance();// 日曆類
// 所有日期月份從0開始
calendar.set(1998, 6, 3, 12, 30, 0);
Date date = calendar.getTime();
// 第二個參數 99
int n = 99;
// 第三個參數 $1000000
int m = 1000000;
// 指定locale 是美國
MessageFormat messageFormat = new MessageFormat(s, Locale.US);
System.out.println(messageFormat.format(new Object[] { date, n, m }));
package com.itheima.i18n;
import java.text.MessageFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import org.junit.Test;
public class MessageFormatTest {
//At 12:30 pm on jul 3,1998, a hurricance destroyed 99 houses and caused $1000000 of damage
@Test
public void test1(){
String str = "At {0,date,full} {1,time,full}, a hurricance destroyed {2,number} houses and caused {3,number,currency} of damage";
MessageFormat format = new MessageFormat(str,Locale.CHINA);
Calendar c = Calendar.getInstance();
c.set(1998, 6, 3, 12, 30, 0);
Date date = c.getTime();
Object [] objs = {date,date,99,1000000};
String result = format.format(objs);
System.out.println(result);
}
}