区域设置

区域设置（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//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语言集合

#### 列表

区域描述｜简写｜十六进制值｜十进制值

南非荷兰语｜af｜0x0436｜1078

南非荷兰语（南非）｜af-ZA

阿姆哈拉语｜am

阿姆哈拉语（埃塞俄比亚）｜am-ET

阿尔巴尼亚语｜sq｜0x041C｜1052

阿拉伯语｜ar

阿拉伯语-阿拉伯联合酋长国｜ar-AE｜0x3801｜14337

阿拉伯语-巴林｜ar-BH｜0x3C01｜15361

阿拉伯语-阿尔及利亚｜ar-DZ｜0x1401｜5121

阿拉伯语-埃及｜ar-EG｜0x0C01｜3073

阿拉伯语-伊拉克｜ar-IQ｜0x0801｜2049

阿拉伯语-约旦｜ar-JO｜0x2C01｜11265

阿拉伯语-科威特｜ar-KW｜0x3401｜13313

阿拉伯语-黎巴嫩｜ar-LB｜0x3001｜12289

阿拉伯语-利比亚｜ar-LY｜0x1001｜4097

阿拉伯语-摩洛哥｜ar-MA｜0x1801｜6145

马普切语｜arn

马普切语（智利）｜arn-CL

阿拉伯语-阿曼｜ar-OM｜0x2001｜8193

阿拉伯语-卡塔尔｜ar-QA｜0x4001｜16385

阿拉伯语-沙特阿拉伯｜ar-SA｜0x0401｜1025

阿拉伯语-叙利亚｜ar-SY｜0x2801｜10241

阿拉伯语-突尼斯｜ar-TN｜0x1C01｜7169

阿拉伯语-也门｜ar-YE｜0x2401｜9217

阿萨姆语｜as

阿萨姆语-印度｜as-IN

亚美尼亚语｜hy｜0x042B｜1067

阿塞拜疆语｜az

阿塞拜疆语-拉丁文｜az-Latn｜0x042C｜1068

阿塞拜疆语-西里尔文｜az-Cyrl｜0x082C｜2092

阿塞拜疆语-拉丁文-阿塞拜疆｜az-Latn-AZ｜0x042C｜1068

阿塞拜疆语-西里尔文-阿塞拜疆｜az-Cyrl-AZ｜0x082C｜2092

巴什基尔语｜ba

巴什基尔语-俄罗斯｜ba-RU

巴斯克语｜eu｜0x042D｜1069

白俄罗斯语｜be｜0x0423｜1059

白俄罗斯语-白俄罗斯｜be-BY

保加利亚语｜bg｜0x0402｜1026

保加利亚语-保加利亚｜bg-BG

孟加拉语｜bn

孟加拉语-孟加拉｜bg-BD

孟加拉语-印度｜bg-IN

藏语｜bo

藏语-中国｜bo-CN

布列塔尼语｜bo

布列塔尼语-法国｜br-FR

波斯尼亚语｜bs

波斯尼亚语（西里尔文）｜bs-Cyrl

波斯尼亚语（西里尔文，波斯尼亚和黑塞哥维那）｜bs-Cyrl-BA

波斯尼亚语（拉丁文）｜bs-Latn

波斯尼亚语（拉丁文，波斯尼亚和黑塞哥维那）｜bs-Latn-BA

加泰隆语｜ca｜0x0403｜1027

加泰罗尼亚语（西班牙）｜ca-ES｜0x0403｜1027

中文｜zh

中文-中国大陆-拼音排序｜zh-CN｜0x0804｜2052

中文-中国大陆-笔画排序｜zh-CN_stroke｜0x20804

中文（简体）｜zh-Hans｜0x0004

中文（繁体）｜zh-Hant｜0x7C04

中文-香港特别行政区｜zh-HK｜0x0C04｜3076

中文-香港特别行政区部首笔画序｜zh-HK_radstr｜0x0C04｜3076

中文-澳门特别行政区｜zh-MO｜0x1404｜5124

中文-澳门特别行政区部首笔画序｜zh-MO_radstr｜0x1404｜5124

中文-澳门特别行政区笔画序｜zh-MO_stroke｜0x1404｜5124

中文-新加坡｜zh-SG｜0x1004｜4100

中文-新加坡笔画序｜zh-SG_stroke｜0x1004｜4100

中文-台湾｜zh-TW｜0x0404｜1028

中文-台湾-Bopomofo排序｜zh-TW｜0x30404

中文-台湾拼音序｜zh-TW_pronun｜0x0404｜1028

中文-台湾部首笔画序｜zh-TW_radstr｜0x0404｜1028

克罗地亚语｜hr｜0x041A｜1050

科西嘉语｜co

科西嘉语（法国）｜co-FR

捷克语｜cs｜0x0405｜1029

捷克语（捷克共和国）｜cs-CZ

威尔士语｜cy

威尔士语（英国）｜cy-GB

丹麦语｜da｜0x0406｜1030

丹麦语（丹麦）｜da-DK｜1030

荷兰语-荷兰｜nl-nl｜0x0413｜1043

荷兰语-比利时｜nl-be｜0x0813｜2067

英语-加勒比｜en-029

英语-澳大利亚｜en-AU｜0x0C09｜3081

英语-伯利兹｜en-BZ｜0x2809｜10249

英语-加拿大｜en-CA｜0x1009｜4105

英语-加勒比｜en-CB｜0x2409｜9225

英语-印度｜en-IN｜0x4009｜16393

英语-爱尔兰｜en-IE｜0x1809｜6153

英语-牙买加｜en-JM｜0x2009｜8201

英语-马来西亚｜en-MY｜0x4409｜17417

英语-新西兰｜en-NZ｜0x1409｜5129

英语-菲律宾｜en-PH｜0x3409｜13321

英语-新加坡｜en-SG｜0x4809｜18441

英语-南非｜en-ZA｜0x1C09｜7177

英语-特立尼达岛｜en-TT｜0x2C09｜11273

英语-英国｜en-GB｜0x0809｜2057

英语-美国｜en-US｜0x0409｜1033

英语-津巴布韦｜en-ZW｜0x3009｜12297

爱沙尼亚语｜et｜0x0425｜1061

波斯语｜fa｜0x0429｜1065

芬兰语｜fi｜0x040B｜1035

法罗语｜fo｜0x0438｜1080

法语-法国｜fr-fr｜0x040C｜1036

法语-比利时｜fr-be｜0x080C｜2060

法语-加拿大｜fr-ca｜0x0C0C｜3084

法语-卢森堡｜fr-lu｜0x140C｜5132

法语-瑞士｜fr-ch｜0x100C｜4108

盖尔语-爱尔兰｜gd-ie｜0x083C｜2108

盖尔语-苏格兰｜gd｜0x043C｜1084

德语-德国-Dictionary排序｜de-DE｜0x0407｜1031

德语-德国-Phone book排序｜de-DE_phoneb｜0x10407

德语-奥地利｜de-AT｜0x0C07｜3079

德语-列支敦士登｜de-LI｜0x1407｜5127

德语-卢森堡｜de-LU｜0x1007｜4103

德语-瑞士｜de-CH｜0x0807｜2055

下索布语｜dsb

下索布语(德语)｜dsb_DE

迪维西语｜dv

迪维西语(马尔代夫)｜dv_MF

希腊语｜el｜0x0408｜1032

希腊语(希腊)｜el-GR｜0x0408｜1032

希伯来语｜he｜0x040D｜1037

印地语｜hi｜0x0439｜1081

匈牙利语｜hu｜0x040E｜1038

冰岛语｜is｜0x040F｜1039

印度尼西亚语｜id｜0x0421｜1057

意大利语-意大利｜it-it｜0x0410｜1040

意大利语-瑞士｜it-ch｜0x0810｜2064

日语｜ja｜0x0411｜1041

朝鲜语｜ko｜0x0412｜1042

拉脱维亚语｜lv｜0x0426｜1062

立陶宛语｜lt｜0x0427｜1063

马其顿｜mk｜0x042F｜1071

马来语-马来西亚｜ms-my｜0x043E｜1086

马来语-文莱｜ms-bn｜0x083E｜2110

马耳他语｜mt｜0x043A｜1082

马拉地语｜mr｜0x044E｜1102

挪威-伯克梅尔｜nb-no｜0x0414｜1044

挪威-尼诺斯克语｜nn-no｜0x0814｜2068

波兰语｜pl｜0x0415｜1045

葡萄牙语-葡萄牙｜pt-pt｜0x0816｜2070

葡萄牙语-巴西｜pt-br｜0x0416｜1046

罗曼什语｜rm｜0x0417｜1047

罗马尼亚语-罗马尼亚｜ro｜0x0418｜1048

罗马尼亚语-摩尔多瓦共和国｜ro-mo｜0x0818｜2072

俄语｜ru｜0x0419｜1049

俄罗斯-摩尔多瓦共和国｜ru-mo｜0x0819｜2073

梵文｜sa｜0x044F｜1103

塞尔维亚语-西里尔字母｜sr-sp｜0x0C1A｜3098

塞尔维亚语-拉丁文｜sr-sp｜0x081A｜2074

茨瓦纳语｜tn｜0x0432｜1074

斯洛文尼亚语｜sl｜0x0424｜1060

斯洛伐克语｜sk｜0x041B｜1051

索布语｜sb｜0x042E｜1070

西班牙语-西班牙 (现代)｜es-es｜0x0C0A｜3082

西班牙语-西班牙 (传统)｜0x040A｜1034

西班牙语-阿根廷｜es-ar｜0x2C0A｜11274

西班牙语-玻利维亚｜es-bo｜0x400A｜16394

西班牙语-智利｜es-cl｜0x340A｜13322

西班牙语-哥伦比亚｜es-co｜0x240A｜9226

西班牙语-哥斯达黎加｜es-cr｜0x140A｜5130

西班牙语-多米尼加共和国｜es-do｜0x1C0A｜7178

西班牙语-厄瓜多尔｜es-ec｜0x300A｜12298

西班牙语-危地马拉｜es-gt｜0x100A｜4106

西班牙语-洪都拉斯｜es-hn｜0x480A｜18442

西班牙语-墨西哥｜es-mx｜0x080A｜2058

西班牙语-尼加拉瓜｜es-ni｜0x4C0A｜19466

西班牙语-巴拿马｜es-pa｜0x180A｜6154

西班牙-秘鲁｜es-pe｜0x280A｜10250

西班牙语-波多黎各｜es-pr｜0x500A｜20490

西班牙语-巴拉圭｜es-py｜0x3C0A｜15370

西班牙语-萨尔瓦多｜es-sv｜0x440A｜17418

西班牙语-乌拉圭｜es-uy｜0x380A｜14346

西班牙语-委内瑞拉｜es-ve｜0x200A｜8202

南部索托语｜st｜0x0430｜1072

斯瓦希里语｜sw｜0x0441｜1089

瑞典语-瑞典｜sv-se｜0x041D｜1053

瑞典语-芬兰｜sv-fi｜0x081D｜2077

泰米尔语｜ta｜0x0449｜1097

鞑靼语｜tt｜0X0444｜1092

泰语｜th｜0x041E｜1054

土耳其语｜tr｜0x041F｜1055

特松加｜ts｜0x0431｜1073

乌克兰语｜uk｜0x0422｜1058

乌都语｜ur｜0x0420｜1056

乌兹别克语-西里尔文｜uz-uz｜0x0843｜2115

乌兹别克语-拉丁文｜uz-uz｜0x0443｜1091

越南语｜vi｜0x042A｜1066

班图语｜xh｜0x0434｜1076

意第绪语｜yi｜0x043D｜1085

祖鲁语｜zu｜0x0435｜1077

## 外部链接

- 微软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