ZetCode

Java Locale

最后修改日期:2024 年 7 月 10 日

本文介绍如何本地化 Java 程序。

国际化 是指设计一个应用程序,使其可以适应各种语言和地区的过程。 本地化 是指为特定地区或语言定制应用程序的过程。

Locale 代表一个特定的地理、政治或文化区域。

Locale 敏感数据包括

默认 Locale

默认的 Locale 通过 Locale.getDefault 确定。

Main.java
import java.util.Locale;

void main() {

    var defLoc = Locale.getDefault();
    System.out.println(defLoc.getDisplayCountry());
    System.out.println(defLoc.getDisplayLanguage());
    System.out.println(defLoc.getDisplayName());
    System.out.println(defLoc.getISO3Country());
    System.out.println(defLoc.getISO3Language());
    System.out.println(defLoc.getLanguage());
    System.out.println(defLoc.getCountry());

    System.out.println("------------------------");

    var skLoc = Locale.of("SK", "sk");
    System.out.println(skLoc.getDisplayCountry());
    System.out.println(skLoc.getDisplayLanguage());
    System.out.println(skLoc.getDisplayName());
    System.out.println(skLoc.getISO3Country());
    System.out.println(skLoc.getISO3Language());
    System.out.println(skLoc.getLanguage());
    System.out.println(skLoc.getCountry());
}

该程序打印默认 Locale 和斯洛伐克 Locale 的属性。

var defLoc = Locale.getDefault();
System.out.println(defLoc.getDisplayCountry());
System.out.println(defLoc.getDisplayLanguage());
System.out.println(defLoc.getDisplayName());

我们获取默认的 Locale 并打印显示国家名称、语言和名称。

$ java Main.java
United States
English
English (United States)
USA
eng
en
US
------------------------
Slovakia
Slovak
Slovak (Slovakia)
SVK
slk
sk
SK

Locale 常量

有一些内置的 Locale 常量,例如 Locale.US

Main.java
import java.text.NumberFormat;
import java.util.Locale;

void main() {

    double n = 1240.35;

    NumberFormat nf = NumberFormat.getInstance(Locale.US);
    System.out.println(nf.format(n));

    NumberFormat nf2 = NumberFormat.getInstance(Locale.FRANCE);
    System.out.println(nf2.format(n));

    NumberFormat nf3 = NumberFormat.getInstance(Locale.GERMAN);
    System.out.println(nf3.format(n));
}

该程序以 Locale.USLocale.FRANCELocale.GERMAN Locale 打印一个数字。

NumberFormat nf = NumberFormat.getInstance(Locale.US);

NumberFormat.getInstance 返回指定 Locale 的通用数字格式。

System.out.println(nf.format(n));

我们将值传递给 NumberFormatformat 方法。

$ java Main.java
1,240.35
1 240,35
1.240,35

Locale.Builder

可以使用 Locale.Builder 创建 Locale。

Main.java
import java.text.NumberFormat;
import java.util.Locale;

void main() {

    double n = 1240.35;

    var loc = new Locale.Builder()
            .setLanguage("sk")
            .setRegion("SK")
            .build();

    NumberFormat nf = NumberFormat.getInstance(loc);
    System.out.println(nf.format(n));

    var loc2 = new Locale.Builder()
            .setLanguage("ja")
            .setRegion("JP")
            .build();

    NumberFormat nf2 = NumberFormat.getInstance(loc2);
    System.out.println(nf2.format(n));
}

该程序本地化斯洛伐克语和日语的值。 Locale 是使用构建器创建的。

var loc = new Locale.Builder()
    .setLanguage("sk")
    .setRegion("SK")
    .build();

Locale 是用构建器构建的。 我们使用 setLanguage 设置语言,使用 setRegion 设置区域。

$ java Main.java
1 240,35
1,240.35

Locale.of 方法

有三种方法可以创建 Locale 对象。

Locale.of(String language)
Locale.of(String language, String country)
Locale.of(String language, String country, String variant)

我们可以将语言、国家/地区和变体指定为参数。

Main.java
import java.math.BigDecimal;
import java.text.NumberFormat;
import java.util.Locale;

void main() {

    var val = new BigDecimal("2530.45");

    var skLoc = Locale.of("sk", "SK");
    var huLoc = Locale.of("hu", "HU");
    var ruLoc = Locale.of("ru", "RU");

    NumberFormat cf1 = NumberFormat.getCurrencyInstance(skLoc);
    System.out.println(cf1.format(val));

    NumberFormat cf2 = NumberFormat.getCurrencyInstance(huLoc);
    System.out.println(cf2.format(val));

    NumberFormat cf3 = NumberFormat.getCurrencyInstance(ruLoc);
    System.out.println(cf3.format(val));
}

在该示例中,我们打印斯洛伐克语、匈牙利语和俄语 Locale 中的货币值。

var val = new BigDecimal("2530.45");

对于货币值,我们应该使用 BigDecimal

NumberFormat cf1 = NumberFormat.getCurrencyInstance(skLoc);

要格式化货币值,我们使用 NumberFormat.getCurrencyInstance 并将 Locale 传递给它。

$ java Main.java
2 530,45 €
2 530,45 Ft
2 530,45 ₽

Locale 格式化日期时间

使用 LocaleDateTimeFormatter,我们可以格式化日期时间值。

Main.java
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;
import java.util.Locale;

void main() {

    var now = LocalDateTime.now();

    var dtf1 = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM)
            .withLocale(Locale.FRANCE);
    System.out.println(now.format(dtf1));

    var dtf2 = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM)
            .withLocale(Locale.US);
    System.out.println(now.format(dtf2));

    var dtf3 = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM)
            .withLocale(Locale.TRADITIONAL_CHINESE);
    System.out.println(now.format(dtf3));
}

在该程序中,我们以法语、美国和中文 Locale 格式化当前日期时间。

var dtf1 = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM)
    .withLocale(Locale.FRANCE);

我们使用 ofLocalizedDateTime 选择日期时间格式样式,并使用 withLocale 设置 Locale。

$ java Main.java
10 juil. 2024, 11:53:59
Jul 10, 2024, 11:53:59 AM
2024年7月10日 上午11:53:59

Locale ResourceBundle

资源包是一个 Java 属性文件,其中包含特定于 Locale 的数据。 我们使用资源包本地化消息。

src/main/resources/words.properties
w1=Earth
w2=ocean

这是默认的属性文件;它通常使用英语。 文件中有两个单词。

src/main/resources/words_de.properties
w1=Erde
w2=ozean

words_de.properties 文件包含德语单词。

src/main/resources/words_ru.properties
w1=Земля
w2=океан

words_ru.properties 文件包含俄语单词。

使用 IntelliJ IDEA 时,我们需要将属性文件的编码更改为 utf-8;默认值为 ISO-8859-1。

Main.java
import java.nio.charset.Charset;
import java.util.Locale;
import java.util.ResourceBundle;

void main() {

    Locale[] locales = {
            Locale.GERMAN,
            Locale.of("ru", "RU"),
            Locale.ENGLISH
    };

    System.out.println("w1:");

    for (Locale locale : locales) {

        getWord(locale, "w1");
    }

    System.out.println("w2:");

    for (Locale locale : locales) {

        getWord(locale, "w2");
    }
}

void getWord(Locale curLoc, String key) {

    ResourceBundle words = ResourceBundle.getBundle("main/resources/words", curLoc);
    String value = words.getString(key);

    System.out.printf("Locale: %s, Value: %s %n", curLoc, value);
}

在代码示例中,我们打印三个资源包中使用的所有单词。

ResourceBundle words = ResourceBundle.getBundle("main/resources/words", curLoc);

使用 ResourceBundle.getBundle 方法,我们获取当前使用的 Locale 的捆绑包。

String value = words.getString(key);

从捆绑包中,我们使用 getString 检索值。

$ java Main.java
w1:
Locale: de, Value: Erde 
Locale: ru_RU, Value: Земля 
Locale: en, Value: Earth 
w2:
Locale: de, Value: ozean 
Locale: ru_RU, Value: океан 
Locale: en, Value: ocean 

来源

Java locale - 语言参考

在本文中,我们展示了如何本地化 Java 程序。

作者

我的名字是 Jan Bodnar,我是一位充满激情的程序员,拥有丰富的编程经验。 自 2007 年以来,我一直在撰写编程文章。 迄今为止,我已经撰写了 1,400 多篇文章和 8 本电子书。 我拥有超过十年的编程教学经验。

列出所有Java教程