【问题标题】:Which "default Locale" is which?哪个“默认语言环境”是哪个?
【发布时间】:2014-06-26 06:01:27
【问题描述】:

对于 UNIX 语言环境,其细分意味着相对完善的文档。

  • LC_COLLATE(字符串排序规则)
  • LC_CTYPE(字符转换)
  • LC_MESSAGES(用户界面中显示的消息)
  • LC_MONETARY(货币值的格式)
  • LC_NUMERIC(非货币数值的格式)
  • LC_TIME(日期和时间值的格式)
  • LANG(如果未设置上述任何一项,则回退)

Java 有不同的分类,与现实世界不太匹配(像往常一样):

  • Locale.getDefault()
  • Locale.getDefault(Locale.Category.DISPLAY)
  • Locale.getDefault(Locale.Category.FORMAT)

如果您阅读这些文档,Locale.getDefault(Locale.Category.DISPLAY) 似乎对应于 LC_MESSAGES,而Locale.getDefault(Locale.Category.FORMAT) 似乎对应于 LC_MONETARY+LC_NUMERIC+LC_TIME 的某种组合。

不过还是有问题。

如果您阅读 JDK 源代码,您会开始发现许多令人担忧的事情。例如,ResourceBundle.getBundle(String) - 完全是关于字符串消息 - 使用 Locale.getDefault(),not Locale.getDefault(Locale.Category.DISPLAY)。

所以我想我想知道的是:

这些方法中的哪一个应该用于什么目的?

相关,但我做了一个小测试程序来查看哪些 Java 语言环境对应于哪些 UNIX 语言环境,并得到了更令人惊讶的结果。

import java.util.Locale;

public class Test {
    public static void main(String[] args) {
        System.out.println("  Unqualified:  " + Locale.getDefault());
        System.out.println("  Display:      " + Locale.getDefault(Locale.Category.DISPLAY));
        System.out.println("  Format:       " + Locale.getDefault(Locale.Category.FORMAT));
    }
}

根据我的 shell 的语言环境:

$ locale
LANG="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_CTYPE="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_ALL="en_US.UTF-8"

程序的输出:

$ java Test
  Unqualified:  en_AU
  Display:      en_AU
  Format:       en_AU

所以事实证明,Java 甚至没有从 UNIX 语言环境中获取它。它必须使用其他后门来获取设置而不使用那些。

【问题讨论】:

    标签: java internationalization locale


    【解决方案1】:

    很难理解你在这里问什么。相反,您发表了一个声明,表明您不是 Java 程序员。没关系,真的无所谓。

    有几点需要澄清:

    换句话说,在 Java 7 之前,Java 的区域设置模型就像一个由语言、国家和可选区域设置变体组成的系统属性一样简单。 Java 7 改变了这种情况(Java 8 进一步扩展了结尾...),现在您有两个系统属性,一个用于格式化,一个用于显示用户界面消息。
    问题是,有大量的遗留代码是用 Java 编写的,当你升级平台时这不应该被破坏。这就是为什么您仍然拥有无参数的Locale.getDefault() 的原因。而且(可以自己测试)Locale.getDefault()和Locale.getDefault(Locale.Category.DISPLAY)基本可以互换。

    现在,我说的是格式和用户界面消息。基本上,格式化不仅仅是格式化,还包括字符大小写转换(LC_CTYPE)、排序规则(LC_COLLATE)等。除了用户界面消息之外的任何东西。有点,因为默认字符编码(取决于操作系统,顺便说一句)不是Locale 的一部分。相反,您需要致电 Charset.defaultCharset()。
    并且可以使用ResourceBundle.Control 类来制定回退规则(内置于Java,而不是从操作系统中读取)。而且我们知道,它与 UI 类别相当相关......

    Java 语言环境模型不同于 POSIX(不是 UNIX,它更通用)的原因很简单,因为那里有很多平台。而且这些平台不需要使用 POSIX……我的意思不仅是操作系统,还包括 web 之类的东西……Java 正在努力实现通用性和多功能性。结果是 Java 的语言环境模型很复杂,运气不好。

    我必须补充一点,如今,不仅是语言和国家,还有首选脚本、日历系统、编号系统、特定排序规则设置等等。它有时甚至可以工作。

    【讨论】:

    • 说到那些旧 API,NumberFormat、DateFormat、MessageFormat 和家庭 确实 更新为使用 getDefault(Locale.Category.FORMAT),而 ResourceBundle 没有更新为使用getDefault(Locale.Category.DISPLAY)。因此,如果我设置 user.language.display 系统属性,除非我还通过我的应用程序和所有第三方库更新对 MessageFormat 的任何调用以显式传递,否则它不会被用于它应该用于的用途正确的语言环境(在我们的应用程序中这样做很实用,但库并不是真的......)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-29
    • 2016-09-07
    • 2014-03-31
    • 1970-01-01
    相关资源
    最近更新 更多