区域设置

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

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

实际落实

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

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

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

locale相关(环境)变量生效的优先顺序:[1]

  1. LANGUAGE 指定个人对语言环境值的主次偏好,例如zh_CN:en_US:en
  2. LC_ALL 这不是一个环境变量,是一个可被C语言库函数setlocale设置的宏,其值可覆盖所有其他的locale设定。因此缺省时此值为空
  3. LC_xxx 可设定locale各方面(category)的值,可以覆盖LANG的值。
  4. LANG 指定默认使用的locale值

可以把上述环境变量设在/etc/profile 或 /etc/environment等系统初始文件中。值得注意的是,若LANG或LC_ALL被设定为 "C",那么LANGUAGE的值将被忽视。 [2]

除 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 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-1ISO 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

参见

外部链接

参考文献

  1. ^ In IBM developerworks网站 王华东:“浅析 Linux 的国际化与本地化机制”. [2014-10-31]. (原始内容存档于2014-10-31). 
  2. ^ A Quick Primer On Unicode and Software Internationalization Under Linux and UNIX by Ed Trager. [2014-11-30]. (原始内容存档于2014-12-04).