1 什么是国际化
比如点击网页上的某个按钮 能进行中英文切换 这就是一种国际化
网页上的语言首选 可以通过浏览器的语言首选项修改
2 概述
软件的本地化:一个软件在某个国家或者地区使用时,采用该国家或地区的语言 数字,货币,日期等习惯
软件的国际化:软件开发时 能够支持多个国家和地区。
在控制面板 区域和语言中 可以看到特定国家的日期显示习惯
随用户区域信息而变化的数据称为本地信息敏感数据 国际化又称为 i18n
3软件国际化的特征 ?
一个国际化的应用软件的特征
1)对于程序中的本地信息敏感数据 等根据当地所在国家的习惯显示
2)对于文本元素 不是直接写在应用程序中 而是存储在应用程序外部的资源文件中 在应用程序中通过程序代码来动态
获得这些数据。
3)无需修改和重新编译程序就能支持新的国家或地区的用户使用
4国际化之Locale类
实例 对象代表一个特定的地理 政治或者文化上的区域
<%--WEB应用中从request中获取Locale --%>
<%=request.getLocale() %>
如果首选语言是中文 则获取到zh-cn 如果是美国 获取EN-US
import java.util.Locale;
public class LocaleTest {
public static void main(String[] args) {
//这样就可以获取一个关联中国的本地化对象
Locale locale=Locale.CHINA;
System.out.println(locale.getLanguage()); //zh
System.out.println(locale.getDisplayCountry()); //中国
System.out.println("---分割线-------");
//创建一个本地化 (一般直接通过Locale 加 点的方式获取就可以了 也可以使用构造函数)
Locale locale2=new Locale("en","US");
System.out.println(locale2.getLanguage());
System.out.println(locale2.getDisplayCountry());
}
}
5 国际化之DateFormat(日期格式转换器)
功能:将一个日期/时间对象格式化为表示某个国家地区的日期/时间字符串 也可以反解析(code理解)
DateFormat 格式化日期的工具类 本身是一个抽象类
1)若只希望 通过DateFormat 把一个Date对象转为一个字符串 则可以通过DateFormat的工厂方法 获取DateFormat对象
2)对于不同的格式化(可以只格式化时间,也可以格式化日期时间)有不同的工厂方法
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
public class DateFormatTest {
public static void main(String[] args) throws ParseException {
//1Date转本地化日期
//本地化对象
Locale locale=Locale.CHINA;
//这个Date获取都是一样的内容
Date date=new Date();
System.out.println(date);
//1) 创建DateFormat对象(使用一个专门转换中国日期时间的日期转换器) 这是一个工厂方法
DateFormat dateFormat=DateFormat.getDateTimeInstance(DateFormat.FULL,DateFormat.MEDIUM,locale);
//2 )开始转换(转换结果是字符串)
String str=dateFormat.format(date);
System.out.println(str);
System.out.println("=================分割线=================");
//2 本地化日期字符串转Date对象
String str2="1990-12-12 12:12:12";
//1)这个时候还得通过DateFormat进行解析(要指定解析的格式)
//要对应上面的字符串 (这类东西知道怎么用就好了 不看源码 是不可能知道原理的)
DateFormat dateFormat2=new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); 这里的参数是pattern
Date date2=dateFormat2.parse(str2);
System.out.println(date2);
}
}
tip:敲代码比看文档更具体 更容易
6NumberFormat(数字格式化对象)
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.Locale;
public class NumberFormatTest {
public static void main(String[] args) throws ParseException {
double d=123456799.123d;
Locale locale=Locale.CHINA;
//1 数字转成某种特定的字符串(数字形式 货币形式_
//1 转换成中国的数字表示形式
NumberFormat numberFormat=NumberFormat.getNumberInstance(locale);
String str=numberFormat.format(d);
System.out.println(str);
//2 转换成中国的货币表示形式
NumberFormat numberFormat2=NumberFormat.getCurrencyInstance(locale);
String str2=numberFormat2.format(d);
System.out.println(str2);
System.out.println("===============分割线===================");
//2 字符串解析成某个数字和货币
String str3="123,456,789.123";
NumberFormat numberFormat3=NumberFormat.getNumberInstance(locale);
double d3=(double) numberFormat3.parse(str3);
System.out.println(d3);
String str4="¥123,456,799.12";
d3=(double) numberFormat2.parse(str4);
System.out.println(d3);
}
}
7 MessageFormat格式转换器
import java.text.DateFormat;
import java.text.MessageFormat;
import java.text.NumberFormat;
import java.util.Date;
import java.util.Locale;
//模式字符串 转换 会用就行
public class MessageFormatTest {
public static void main(String[] args) {
String str="Date:{0},Salary:{1}";
Locale locale=Locale.CHINA;
Date date=new Date();
double sal=123456.12;
DateFormat dateFormat=DateFormat.getDateInstance(DateFormat.MEDIUM,locale);
String dateStr=dateFormat.format(date);
NumberFormat numberFormat=NumberFormat.getCurrencyInstance(locale);
String salStr=numberFormat.format(sal);
String result=MessageFormat.format(str,dateStr,salStr);
System.out.println(result);
}
}
8 ResourseBundle
1 在类路径下需要由对应的资源文件 baseName.properties 其中baseName是基名
2 可以使用baseName_语言代码_国家代码.properties来添加不同国家或地区的资源文件 如i18n_zh_CN.properties
3 要求所有基名的key都一样
4 可以使用asciinative来得到汉字对应的Ascii码 eclipse有内置的功能
5 可以调用ResourceBundle的getBundle(基名,Locale实例)获取ResourceBundle对象
6 可以调用ResourceBundle的getString(key)来获取资源文件的value字符串的值
7 结合DateFormat,NumberFormat,MessageFormat 即可实现国际化
实例
import java.text.DateFormat;
import java.text.MessageFormat;
import java.text.NumberFormat;
import java.util.Date;
import java.util.Locale;
import java.util.ResourceBundle;
public class TestResourceBundle {
public static void main(String[] args) {
//会找到对应的properties文件 i18n_zh_cn
Locale locale=Locale.CHINA;
ResourceBundle resourceBundle=ResourceBundle.getBundle("i18n",locale);
// System.out.println(resourceBundle.getString("date"));
// System.out.println(resourceBundle.getString("salary"));
String dateLabel=resourceBundle.getString("date");
String salLabel=resourceBundle.getString("salary");
String str="{0}:{1},{2},{3}";
Date date=new Date();
double sal=123456.12;
DateFormat dateFormat=DateFormat.getDateInstance(DateFormat.MEDIUM,locale);
String dateStr=dateFormat.format(date);
NumberFormat numberFormat=NumberFormat.getCurrencyInstance(locale);
String salStr=numberFormat.format(sal);
String result=MessageFormat.format(str,dateLabel,dateStr,salLabel,salStr);
System.out.println(result);
}
}
9国际化之fmt标签 上面都是一些原理(其实只是表面的原理 深层的可以看源码)
JSTL中提供了标签来进行国际化(别人封装好了。。。)直接使用标签进行国际化
实例
<%@page import="java.util.Locale"%>
<%@page import="java.util.Date"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
Date date=new Date();
request.setAttribute("date", date);
request.setAttribute("salary", 12345.67);
%>
<%
String code=request.getParameter("code");
if(code!=null)
{
if("en".equals(code))
session.setAttribute("locale", Locale.US);
else if("zh".equals(code))
session.setAttribute("locale", Locale.CHINA);
}
%>
<%--自动获取locale --%>
<%--
<fmt:bundle basename="i18n">
<fmt:message key="date"></fmt:message>
<fmt:formatDate value="${date}" />
<fmt:message key="salary"></fmt:message>
<fmt:formatNumber value="${salary}"/>
</fmt:bundle>
--%>
<c:if test="${sessionScope.locale!=null}">
<fmt:setLocale value="${sessionScope.locale}"/>
</c:if>
<fmt:setBundle basename="i18n"/>
<fmt:message key="date"></fmt:message>
<fmt:formatDate value="${date}" dateStyle="FULL"/>
<fmt:message key="salary"></fmt:message>
<fmt:formatNumber value="${salary}" type="currency"/>
<br> <br>
<a href="index.jsp?code=en">English</a>
<a href="index.jsp?code=zh">中文</a>
</body>
</html>
tip:不要纠结概念 会写会听就足够
更深入的标签使用看更具体的api