java国际化——Locale+数字格式

来源:互联网 发布:c seo的伪静态 编辑:程序博客网 时间:2024/06/05 00:47

【0】README

1) 本文部分文字描述转自 core java volume 2 , 测试源代码均为原创, 旨在理解 java国际化——Locale+数字格式 的基础知识 ;
2) java 编程语言是第一个设计成为全面支持国际化的语言。

  • 2.1)从一开始, 它就具备了进行有效的国际化所必须 的一个重要特性: 使用 Unicode 来处理所有字符串; (干货——java 使用 Unicode 来处理所有字符串 全面支持国际化)

【1】Locales

1)有若干个专门负责格式处理的类。 为了对格式化进行控制, 可以使用Locale类。它描述了: 一种语言;一个位置;一段脚本(java 7 开始支持);一个变体;
2)看个荔枝:指定诸如方言或拼写规则之类的杂项, 如,

  • 2.1)在美国, Locale 对象包含language=English, location=UnitedStates
  • 2.2)瑞士有四种官方语言(德语, 法语, 意大利语和力拓罗曼史语),一个说德语的瑞士人使用的 Locale 是: (干货——说德语的瑞士人的Locale表示)
    langage=German , location = Switzerland ;
  • 2.3)Locale 有两个属性: 表达语言(本地代码,遵循ISO-639-1)+位置(国家代码, 遵循ISO-3166-1)
    这里写图片描述

3) 创建Locale 对象:(只要提供了语言代码或语言与国家代码), 也就是说至少要提供语言代码:

Locale german = new Locale(“de”);
Locale germanGermany = new Locale(“de”, “DE”);
Locale germanSwitzerland = new Locale(“de”, “CH”); //说德语的瑞士人;

4)为方便起见,java SE 预定了大量的Locale对象 和 语言Locale:

5)还有其他两种方法获得一个 Locale 对象:

  • 5.1) Locale类的静态方法 getdefault 方法:可以获得作为本地os 的一部分而存放的默认 Locale;
  • 5.2)setDefault方法:改变默认的 Locale, 但是,这种改变只对你的程序有效, 不会对os 产生影响;

6)最后, 对于所依赖的Locale 的类,可以返回一个它们所支持的Locale 数组, 如:

Locale[] locales = DateFormat.getAvailabelLocales(); 将返回 所有 DataFormat 类所能够处理的 Locale ;

Attention)命令行设置 默认 Locale:
java -Duser.languge\=\de -Duser.region=CH MyClass
7)一旦有了 Locale对象,做的事情很有限。

  • 7.1)getdisplayName方法:而是以一种面向用户的形式来表现, 如 German (Switzerland)
  • 7.2)problem+solution
    • 7.2.1)problem:显示的名字是默认的 locale 来表示的, 这是不恰当的。 如果你的用户已经选择了 德语作为首选语言, 那么你希望用德语显示字符串;
    • 7.2.2)solution: 通过将 GermanLocale 作为参数传递就可以做到这一点:

      Locale loc = new Locale(“de”, “CH”);
      out.println(loc.getDisplayName(Locale.GERMAN)); // 打印出 Deutsch(Schweiz)


8)看个荔枝(测试Locale):
  • 8.1)for souce code, please visit : https://github.com/pacosonTang/core-java-volume/blob/master/coreJavaAdvanced/chapter5/LocalesTest.java
  • 8.2)key source code at a glance:
public static void main1(String[] a)    {        // 获得作为本地OS的一部分而存放的默认Locale        Locale l = Locale.getDefault();        System.out.println("   Language, Country, Variant, Name");        System.out.println(" ");        System.out.println("Default locale: ");        System.out.println("   " + l.getLanguage() + ", " + l.getCountry()                + ", " + ", " + l.getVariant() + ", " + l.getDisplayName());        // Locale(language, contury)        // Locale.CANADA_FRENCH == Locale(FRENCH, CANADA )        l = Locale.CANADA_FRENCH;        System.out.println("A predefined locale - Locale.CANADA_FRENCH:");        System.out.println("   " + l.getLanguage() + ", " + l.getCountry()                + ", " + ", " + l.getVariant() + ", " + l.getDisplayName());        l = new Locale("en", "CN");        System.out.println("User defined locale -Locale(\"en\",\"CN\"):");        System.out.println("   " + l.getLanguage() + ", " + l.getCountry()                + ", " + ", " + l.getVariant() + ", " + l.getDisplayName());        Locale[] s = Locale.getAvailableLocales();        System.out.println("Supported locales: ");        for (int i = 1; i <= 10; i++)        {            System.out.println("   " + s[i].getLanguage() + ", "                    + s[i].getCountry() + ", " + s[i].getVariant() + ", "                    + s[i].getDisplayName());        }    }
  • 8.3)relative printing results as follows:
    这里写图片描述

【2】数字格式

1) 数字和货币高度依赖于 locale的;
2) java 提供了格式器, 可以对 java.text 包中的 数字值进行格式化和解析;
3)通过如下步骤来对特定 Locale 的数字进行格式化:

  • step1)创建 Locale 对象;
  • step2) 使用工厂方法得到一个格式器对象; 工厂方法是 NumberFormat 类的静态方法, 它们接收一个 Locale类的参数,总共有3个工厂方法: getNumberInstance, getCurrencyInstance, getPercentInstance , 这些方法返回的对象可以分别用数字, 货币量和 百分比进行格式化和解析;
    step3) 使用这个格式器对象来完成格式化和解析工作;

  • 3.1)看个荔枝: 如何对德语中的货币值进行格式化:

    Locale locale = new Locale(“de”, “DE”);
    NumberFormat format = NumberFormat.getCurrencyInstance(locale);
    double amt = 65545454.8976;
    string result = format.format(amt);
    这里写图片描述

  • 3.2)看个荔枝: 想要读取一个按照某个 Locale 的惯用法而输入或存储的数字, 使用parse 方法进行解析:

    TextField inputField;

    NumberFormat format = NumberFormat.getNumberInstance();
    //get the number formatter for default locale
    Number input = format.parse(inputFiled.getText().trim());
    double x = input.doubleValue();
    这里写图片描述

对以上代码的分析(Analysis):

  • A1) parse 的返回类型是抽象的 Number 类型;
  • A2)返回的对象是一个 Double 或 Long 的包装器对象, 这取决于被解析的数字是否是浮点数;
  • A3)如果不关心两者的差异, 可以直接使用 Number 类中的 doubleValue 方法来读取被包装的数字;

Warning)

  • W1) Number 类型的对象并不能自动转换为 相关的基本类型, 因此不能直接将一个Number 对象赋给一个基本类型, 而应该使用 doubleValue 或 intValue 方法; (干货——Number 类型的对象并不能自动转换为 相关的基本类型)

3.3) 如果数字文本的格式不正确,会抛出 ParseException; (干货——任何跟在数字之后的字符都将被忽略, 所以这些跟在后面的字符是不会引起异常的);

Attention)

  • A1) 有 getXXInstance 工厂方法返回的类并非是 NumberFormat 类型的;
  • A2) NumberFormat类型是一个抽象类型,而我们实际上得到的格式器是它的一个子类;
  • A3)工厂方法只知道如何定位属于 特定Locale 的对象;
  • A4) 可以用静态的 getAvailableLocales 方法: 得到一个当前所支持的Locale对象列表。 这个方法返回一个Locale 对象数组, 从中可以获得针对他们的数字格式器对象;

【3】货币

1)problem+solution:

  • 1.1)problem: 有一张货物单,货单中有些货物用美元表示,有些用欧元表示, 则,你不能只是使用两种格式器:

    NumberFormat format1 = NumberFormat.getCurrencyInstance(Locale.US);
    NumberFormat format2 = NumberFormat.getCurrencyInstance(Locale.GERMANY);
    //这样一来,发票会很奇怪。 有些金额的格式是 $100,而另一些如 €100.00

  • 1.2) solution: 应该使用 Currency 类来控制 被格式器所处理的货币。可以通过将一个货币识别符传给静态的 Currency.getInstance 方法来得到一个 Currency 对象,然后对每个格式器都调用 setCurrency 方法; (干货——引入货币识别符)

2)看个荔枝: 下面展示如何为你的美国客户设置欧元的格式:

NumberFormat euroFormatter = NumberFormat.getCurrencyInstance(Locale.US);
euroFormatter.setCurrency(Currency.getInstance(“EUR”));

3)货币符号是 由 ISO 4217定义的, 如下表所示:
这里写图片描述

4)看个荔枝(测试Locale):

  • 4.1)for souce code, please visit : 同上;
  • 4.2)key source code at a glance:

    // 设置货币的显示格式    public static void currencyFormatAgain()    {        double num = 123.456;        NumberFormat defaultFormat = NumberFormat.getCurrencyInstance();        System.out.println("default: " + defaultFormat.format(num));        // 说英语的中国人        Locale chinese = new Locale("en", "CN");        NumberFormat englishFormat = NumberFormat.getCurrencyInstance(chinese);        System.out.println(englishFormat.format(num));    }
  • 4.3)relative printing results as follows:
    这里写图片描述

0 0
原创粉丝点击