区域设置

区域设置（locale），也称作“本地化策略集”、“本地环境”，是表达程序用户地区方面的软件设定。不同系统、平台、与软件有不同的区域设置处理方式和不同的設定范围，但是一般区域设置最少也会包括语言和地区。操作系统的区域设置通常比较复杂。区域设置的内容包括：数据格式、货币金额格式、小数点符号、千分位符号、度量衡单位、通货符号、日期写法、日历类型、文字排序、姓名格式、地址等等。

区域设置的主要目标是让用户选择最适合他自己的设定。比如用以上的Windows作比喻：在控制面板的区域和语言选择中，用户可以选择自己的字符集排序方法；当浏览文件时，系统会使用「用户选择的排序」来排列文件。

实际落实
计算机中一套定义用户的语言、国家和用于定义用户希望在其用户界面上看到的各种可以改变的选择的参数集合。通常一个区域设置标识符至少包括一个语言标识符和一个区域标识符。

在UNIX和Windows中，区域设置的控制是不同的。在UNIX下，通常通过环境变量来控制区域设置。这些环境变量包括：LC_ALL, LC_CTYPE, LC_TIME, 等等。你可以通过改变这些环境变量来控制你的程序或者命令所表现出来的区域设置，前提是这些程序或者命令必须是已经被国际化的和本地化的。在Windows下，你可以通过改变控制面板上的“语言/区域”中的区域的值来设定Windows的当前用户的区域设置。

Ubuntu操作系统
在Ubuntu操作系统中，使用man locale-gen或man locale可获得关于locale实现的细节。实际上是由glibc库实现的。

locale相关（环境）变量生效的优先顺序：
LANGUAGE 指定个人对语言环境值的主次偏好，例如zh_CN:en_US:en
LC_ALL 这不是一个环境变量，是一个可被C语言库函数setlocale设置的宏，其值可覆盖所有其他的locale设定。因此缺省时此值为空
LC_xxx 可设定locale各方面（category）的值，可以覆盖LANG的值。
LANG 指定默认使用的locale值
可以把上述环境变量设在/etc/profile 或 /etc/environment等系统初始文件中。值得注意的是，若LANG或LC_ALL被设定为 "C"，那么LANGUAGE的值将被忽视。 

除 C 和 POSIX这两个locale名称外，locale的名称并未标准化。Linux平台与Windows系统的locale名称有很大不同。Linux名称的命名规则为：
  language[_territory[.codeset]][@modifier]
其中language是ISO 639-1标准中定义的双字母的语言代码，territory是ISO 3166-1标准中定义的双字母的国家和地区代码，codeset是字符集的名称 (如 UTF-8等)，而 modifier 则是某些 locale 变体的修正符。

bash中的使用示例：
 $ LC_TIME=en_US.UTF-8 date
 Fri Oct 31 19:51:16 CST 2014
 $ LC_TIME=fi_FI.UTF-8 date
 pe 31.10.2014 19.52.00 +0800
 $ LC_TIME=zh_CN.UTF-8 date
 2014年 10月 31日 星期五 19:53:07 CST

相关系统文件：
在文件/usr/share/i18n/SUPPORTED中，列出了当前系统支持的所有locale与字符集的名字。
在目录/var/lib/locales/supported.d/下，列出了当前系统已经生成的所有locale的名字。 
在文件/var/lib/locales/supported.d/local中，列出了所有想要生成或已经生成的locale的名字
在目录/usr/lib/locale/<locale_name>/LC_*，用locale-gen编译出的locale文件
在文件/usr/lib/locale/locale-archive中，包含了很多本地已经生成的locale的具体内容，因此这个文件往往很大。使用命令localedef管理这一文件。使用locale-gen命令编译出来的locale内容默认写入该文件中。
在文件/etc/default/locale中，可以手动配置locale环境变量，LC_CTYPE之类
在目录/usr/share/i18n/charmaps下，缺省的charmap存放路径
在目录/usr/share/i18n/locales下，缺省的locale source file存放路径

相关系统命令：
locale 列出当前采用的各项本地策略，这些由LC_*环境变量定义
locale charmap 列出系统当前使用的字符集
locale -a  列出系统中已经安装的所有locale
locale -m  列出系统中已经安装的所有charmap
locale-gen --purge  将/usr/lib/locale/里面的locale支持文件删掉
编辑文件/var/lib/locales/supported.d/local，增加需要的locale与字符集名字，如：
 en_US.UTF-8 UTF-8
 cs_CZ.UTF-8 UTF-8
 cs_CZ.iso88592 iso88592
 zh_CN.UTF-8 UTF-8
 zh_CN.GBK GBK
 zh_CN.GB2312 GB2312
 zh_CN.GB18030 GB18030
保存并关闭此文件。运行sudo dpkg-reconfigure --force locales，则重新生成字符集。
或者使用命令sudo locale-gen en_US.UTF-8，生成制定的locale  en_US.UTF-8，并把这个locale名字加入文件/var/lib/locales/supported.d/local中
或者使用命令sudo locale-gen，生成所有列在文件/var/lib/locales/supported.d/local中的locale
或者
 cd /usr/share/locales
 sudo ./install-language-pack zh_CN
也可以安装zh_CN的相关语言包。
或者使用命令localedef -f UTF-8 -i zh_CN zh_CN.UTF8，从字符映射文件UTF-8，locale源文件zh_CN，编译出locale称为zh_CN.UTF8，存放入文件/usr/lib/locale/locale-archive中
使用命令localedef --list-archive，列出文件/usr/lib/locale/locale-archive中所有可用的locale的名字
sudo apt-get install language-selector language-env language-pack-zh-hans language-pack-zh-hant 安装中文语言包
sudo nano /etc/default/locale  修改该文件内容。

Windows操作系统
Windows SDK规定，“语言”是与沟通有关的一组属性的集合，包括所有允许的字符、通货符号、日期时间格式等等。每个“语言”有一个语言名字与语言标识符。语言往往还需要指出国家/地区，如“英语（美国）”使用的语言名字是“en-US”。

每个区域设置（locale）是一个“语言”及一个排序规则。Windows XP支持超过150个区域设置（locale）；Windows Vista支持超过200个区域设置（locale）;Windows 7支持至少365个区域设置（locale）。每个区域设置（locale）有区域设置名字(Locale Name )与区域设置标识符(Locale ID ,LCID )。例如："de-DE_phoneb"是德国德语使用德式电话薄排序规则（该排序规则与拉丁字母序稍有不同）。
「区域标识符」(Locale ID ,LCID )为32位的值，在程序设计中经常用到。LCID构成为：
 +-------------+---------+-------------------------+-------------------------+
 |   Reserved  | Sort ID |     SubLanguage ID      |   Primary Language ID   |
 +-------------+---------+-------------------------+-------------------------+
 31         20 19     16 15                    10  9                         0   bit
LCID的低10位是主语言（primary language）的ID；高6位指定次语言（sublanguage）。LCID的低16位称为语言标识符（language identifier），数据类型名为LANGID。例如，中文作为主语言，编号是0x04。作为次语言的台湾中文的编号是0x01；简体中文的编号是0x02，香港中文是0x03，新加坡中文是0x04，澳门中文是0x05。因此，“中国大陆简体中文”的区域标识符等于次语言的标识0x02左移10位，再加上主语言的标识0x04，即(0x02<<10)+0x04=2052，所以简体中文的LCID是2052。类似的，可以算出繁体中文的LCID是1028。美国英语的LCID是1033。使用Windows预定义宏，MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED)的结果也是2052。所有的语言-国家地区列表见：MSDN:Language Identifier Constants and Strings

排序标识符（Sort Order Identifier）占4位，用于表示排序的方法。如简体中文有SORT_CHINESE_PRC（笔划序）、SORT_CHINESE_PRCP（拼音序）。例如，使用笔划序的简体中文的locale名字为"zh-CN_stroke"。所有排序规则列表见：Sort Order Identifiers。

区域设置名字(Locale Name )的命名格式为： 
 locale ::
     primaryLanguage[-Script][-SubLanguage[_sortorder]]
    | "locale-name"
    | "language[_countryORregion[.CodePage]]"
    | ".CodePage"
    | "C"
    | ""
    | NULL
可理解为：
primaryLanguage是ISO 639-1或ISO 639-2/T中定义的语言缩写的小写形式；
Script是ISO 15924定义的书写系统的首字母大写的4字母表示。例如，拉丁字母拼写的乌兹别克语为“uz-Latn-UZ”。
SubLanguage是ISO 3166-1中定义的国家/地区二位字母代码的大写形式；例如：zh-CN_stroke的值为MAKELCID(MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED), SORT_CHINESE_PRC)，即133124。
locale-name形式是简短的标准化字符串，见表的Language tag栏目。a short, IETF-standardized string; for example, en-US for English (United States) or bs-Cyrl-BA for Bosnian (Cyrillic, Bosnia and Herzegovina). These forms are preferred. For a list of supported locale names by Windows operating system version, see the Language tag column of the table in Appendix A: Product Behavior in [MS-LCID]: Windows Language Code Identifier (LCID) Reference. This resource lists the supported language, script, and region parts of the locale names. For information about the supported locale names that have non-default sort orders, see the Locale name column in Sort Order Identifiers. Under Windows 10 or later, locale names that correspond to valid BCP-47 language tags are allowed. For example, jp-US is a valid BCP-47 tag, but it is effectively only US for locale functionality.
同一个区域设置（locale），可以有多种字符集编码表示。例如，Windows操作系统的简体中文的默认编码字符集（即代码页）是GBK，即“936 (ANSI/OEM - Simplified Chinese GBK)”。而Linux操作系统统一使用UTF8字符集，所以Linux简体中文的默认编码字符集是UTF8。所有代码页列表见：Code Page Identifiers。如果需要指出使用的代码页，在上述字符串最后用“.”区隔，后跟Windows代码页数字或者“ACP”、“OCP”。例如："French_Canada.1252"。指定代码页只适用于 LC_ALL或LC_CTYPE。
可以对当前默认的locale只指明代码页，形如".code_page"。使用用户缺省语言与国家地区设置，即来自GetUserDefaultLocaleName()的结果。不建议采用此种方式，因为可能会产生不一致结果。

对于C标准库函数setlocale()，指定参数locale的基本格式为：
 Locale Name | language[_country_region[.code_page]] 
上述language与country_region一般不用缩写，详细列表见National Language Support (NLS) API Reference。例如，对与中文简体，使用字符串"chinese"、"chinese-simplified"、"chinese_CHN"、"chs"，都能得到"Chinese (Simplified)_People's Republic of China.936"效果。 

操作系统有一个当前区域设置。用户可以在控制面板的区域设置中改变它。每个区域设置有许多相关的信息，编程时可以用Locale information types获取这些值的信息。操作系统赋予每个线程一个区域设置，初始值为LOCALE_SYSTEM_DEFAULT

相关系统API函数：
GetUserDefaultLCID 获取当前用户的缺省LCID。对于简体中文操作系统返回值为2052
GetUserDefaultLocaleName 获取当前用户的缺省locale的名字。对于简体中文操作系统该名字为zh-CN
GetSystemDefaultLCID 获取系统的缺省LCID。对于简体中文操作系统返回值为2052
GetSystemDefaultLocaleName 获取系统缺省locale的名字
GetThreadLocale() 获取当前线程的LCID
SetThreadLocale 设置当前线程的LCID。
IsValidLocaleName 判断一个字符串是否为当前操作系统支持的locale的名字
LocaleNameToLCID 从locale的名字获取它的LCID
GetLocaleInfoEx 获取指定locale的各方面的信息
EnumSystemLocalesEx 枚举当前操作系统支持的所有的locale的名字
EnumCalendarInfoExEx 枚举指定locale的日历数据。例如zh-TW有两个日历型，分别为“格里历（本地）”与“格里历（英文）”。
EnumDateInfoExEx 枚举指定locale的各种calendar的日期格式。
GetCalendarInfoEx 查询指定locale指定日历型的指定方面的数据。
GetDateFormatEx 把时间数据转换为指定格式的日期字符串。
GetTimeFormatEx 把时间数据转换为指定格式的时间字符串。
GetDurationFormatEx 把一段持续时间的数据转换为指定格式的字符串。
EnumSystemLanguageGroups 同一语言组可能共享键盘布局、输入法、TT字体、代码页翻译表等等。
GetSystemDefaultLangID 系统缺省的非Unicode语言
GetKeyboardLayout  当前进程的输入法
GetSystemDefaultUILanguage 菜单、对话框、Windows消息、INF文件、帮助文件等的默认语言
GetSystemPreferredUILanguages 操作系统使用的菜单、对话框、Windows消息、INF文件、帮助文件等的语言
GetUserDefaultUILanguage 用户使用的菜单、对话框、Windows消息、帮助文件等的语言
GetUserPreferredUILanguages 用户使用的菜单、对话框、Windows消息、帮助文件等的语言集合
GetThreadPreferredUILanguages  当前线程使用的UI语言集合

列表

参见
国际化与本地化
iconv
gettext

外部链接
微软MSDN中的区域标识符列表（英文） http://msdn.microsoft.com/en-us/library/0h88fahh.aspx
https://web.archive.org/web/20110925084131/http://www.chinaue.com/tool/vbs/html/vsmsclcid.htm

参考文献

计算机编程
國際化與在地化