前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring周边:国际化、Format

Spring周边:国际化、Format

作者头像
WEBJ2EE
发布2019-11-06 19:19:47
7000
发布2019-11-06 19:19:47
举报
文章被收录于专栏:WebJ2EEWebJ2EE

Java 编程语言是第一种设计成为全面支持国际化的语言。 《Java 核心技术 卷二》

1. Locale

Locale 类代表一个特定的地理、语言和国家环境。Locale 向一些对国家和语言、地理等比较敏感的类提供国家地区语言信息,这些类有DateFormat、NumberFormat等等。

1.1. Locale 的构成

Locale 核心由2部分构成:

  • 语言:由2个或3个小写字母(ISO-639-1)表示。例如:Chinese:zh;
  • 国家或地区:由2个大写字母(ISO-3166-1)或三个数字(UN M.49)表示。例如:China:CN;

常见的 ISO-639-1语言代码:

  • Chinese:zh
  • Japanese:ja
  • Italian:it
  • English:en
  • French:fr
  • German:de
  • Spanish:es

常见的 ISO-3166-1 国家代码:

  • China:CN
  • Japan:JP
  • Germany:DE
  • Canada:CA

1.2. 创建 Locale

Locale 的构造函数:

代码语言:javascript
复制
public Locale(String language)
public Locale(String language, String country)

Locale 也预定义了一些国家、语言的 Locale:

代码语言:javascript
复制
// for language
Locale.ENGLISTH
Locale.FRENCH
Locale.JAPANESE
Locale.CHINESE
Locale.SIMPLIFIED_CHINESE
Locale.TRADITIONAL_CHINESE

// for country
Locale.FRANCE
Locale.JAPAN
Locale.CHINA

1.3. 获取 Locale

代码语言:javascript
复制
public static Locale getDefault()
public static Locale[] getAvailableLocales()

示例1:获取当前 JVM 实例的默认 Locale:

代码语言:javascript
复制
public static void main(String[] args) {
    Locale l = Locale.getDefault();
    System.out.println(l.getDisplayName());
    System.out.println(l.toLanguageTag());
}

示例2:获取当前 JVM 支持的所有 Locale:

代码语言:javascript
复制
public static void main(String[] args) {
    Locale[] locales = Locale.getAvailableLocales();
    for(Locale locale : locales){
        System.out.println(locale.getDisplayName()+","+locale.toLanguageTag());
    }
}

2. Locale 与 Format 间关系

数字、货币、日期的格式是高度依赖 locale 的。Java 类库提供了一个格式器(formatter)对象的集合,用于处理它们的格式化和解析操作。

图2-1:Format 及其实现类

3. NumberFormat

3.1. 概述

类间结构:

图3-1:NumberFormat 与 DecimalFormat

关键信息:

  • NumberFormat 是个抽象类;
  • DecimalFormat 虽然是 NumberFormat 的子类,但不要自己去 new,应该通过 NumberFormat 的各种 getXXInstance 接口获取实例;
  • 如果想使用 DecimalFormat 的特殊接口,可通过向下转型实现。(对于绝大多数Locale,NumberFormat 取到的实例都是 DecimalFormat,但也最好加上 try .. catch)。
  • NumberFomart 的各种 getXXInstance 可用于对“整数”、“百分比”、“科学计数”、“数字”的格式化实例。
  • 线程不安全。

图3-2:NumberFormat 的各种 getXXInstance() 方法

3.2. 整数格式化(getIntegerInstance())

获取整数格式化器:

代码语言:javascript
复制
NumberFormat integerInstance = NumberFormat.getIntegerInstance();

getIntegerInstance() 帮你预设的格式化、解析参数:

  • 解析控制:只解析整数部分
  • 格式化控制:小数位数0;
  • 格式化控制:不显示小数分隔符;

图3-3:IntegerInstance 预设的控制参数

示例1:简体中文 Locale 下的数字格式化

代码语言:javascript
复制
package webj2ee;

import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Locale;

public class JdkLoggingDemo {
    public static void main(String[] args) {
        NumberFormat fmt = NumberFormat.getIntegerInstance(Locale.SIMPLIFIED_CHINESE);

        // 常规操作
        System.out.println(fmt.format(Math.PI));

        // 舍入特性:
        fmt.setRoundingMode(RoundingMode.HALF_UP); // 四舍五入
        System.out.println(fmt.format(3.5));

        // 分组特性:
        fmt.setGroupingUsed(true);
        System.out.println(fmt.format(Integer.MAX_VALUE));

        // 控制最大整数位数:
        fmt.setMaximumIntegerDigits(5);
        System.out.println(fmt.format(Integer.MAX_VALUE));

        // 控制最大整数位数:
        fmt.setMinimumIntegerDigits(5);
        System.out.println(fmt.format(Math.PI));

        // ---------------- 向下转型为 DecimalFormat,精细化控制;
        DecimalFormat dfmt = (DecimalFormat)fmt;
        dfmt.setPositivePrefix("+");
        System.out.println(dfmt.format(Math.PI));
        System.out.println(dfmt.format(-Math.PI));
    }
}

示例2:德国 Locale 下的数字格式化

代码语言:javascript
复制
NumberFormat fmt = NumberFormat.getIntegerInstance(Locale.GERMANY);
// ... 后面不变

示例3:德国 Locale 下的数字格式化

代码语言:javascript
复制
NumberFormat fmt = NumberFormat.getIntegerInstance(Locale.FRANCE);

3.2. 货币格式(getCurrencyInstance())

代码语言:javascript
复制
public static void main(String[] args) {
    NumberFormat fmt = NumberFormat.getCurrencyInstance(Locale.SIMPLIFIED_CHINESE);
    System.out.println(fmt.format(Math.PI));

    NumberFormat fmt1 = NumberFormat.getCurrencyInstance(Locale.US);
    System.out.println(fmt1.format(Math.PI));

    NumberFormat fmt2 = NumberFormat.getCurrencyInstance(Locale.FRANCE);
    System.out.println(fmt2.format(Math.PI));
}

3.3. 百分比格式

代码语言:javascript
复制
public static void main(String[] args) {
    NumberFormat fmt = NumberFormat.getPercentInstance(Locale.SIMPLIFIED_CHINESE);
    fmt.setMinimumFractionDigits(2);
    System.out.println(fmt.format(Math.PI/100f));
}

4. DateFormat

4.1. 概述

类间结构:

关键信息:

  • DateFormat 是个抽象类;
  • SimpleDateFormat 虽然是 DateFormat 的子类,但不要自己去 new,应该通过 DateFormat 的各种 getXXInstance 接口获取实例;
  • 如果想使用 SimpleDateFormat 的特殊接口,可通过向下转型实现。
  • 线程不安全;

示例:

代码语言:javascript
复制
public static void main(String[] args) {
    DateFormat fmt = DateFormat.getInstance();
    SimpleDateFormat sdf = (SimpleDateFormat)fmt;
    sdf.applyPattern("yyyy-MM-dd HH:mm:ss SSS");
    String ret = sdf.format(new Date());
    System.out.println(ret);
}

4.2. Date and Time Patterns

特殊的地方:

  • Month:如果用【>=3个 M】描述月份,则月份将被转换为【文字】;

5. MessageFormat

Java 类库中有一个 MessageFormat 类,它与用 printf 方法进行格式化很类似,但是它支持 Locale,并且会对数字和日期进行格式化。

5.1. Patterns and Their Interpretation

5.2. 示例

示例1:

代码语言:javascript
复制
public static void main(String[] args) {
    // ArgumentIndex 必须是非负整数,而且它的个数不只限于0到9这10个。
    String message = "{0}{1}{2}{3}{4}{5}{6}{7}{8}{9}{10}{11}{12}{13}{14}{15}{16}";
    Object[] array = new Object[]{"A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q"};
    String value = MessageFormat.format(message, array);
    System.out.println(value);
}

示例2:

代码语言:javascript
复制
public static void main(String[] args) {
    // 格式化字符串时,两个单引号才表示一个单引号,单个单引号会被省略
    String message1 = "oh, {0} is 'a' pig";
    String message2 = "oh, {0} is ''a'' pig";
    Object[] array = new Object[]{"ZhangSan"};
    String value1 = MessageFormat.format(message1, array);
    String value2 = MessageFormat.format(message2, array);
    System.out.println(value1);
    System.out.println(value2);
}

示例3:

代码语言:javascript
复制
public static void main(String[] args) {
    String message = "oh, {0,number,#.#######} is PI!";
    Object[] array = new Object[]{Math.PI};
    String value = MessageFormat.format(message, array);
    System.out.println(value);
}

参考:

Standard country or area codes for statistical use (M49): https://unstats.un.org/unsd/methodology/m49/ Class MessageFormat: https://docs.oracle.com/javase/8/docs/api/java/text/MessageFormat.html 《Java 核心技术 卷二》 《Java 编程思想》 《Java 8 编程参考官方教程》

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-11-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 WebJ2EE 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档