前言#
今天来看一个比较神秘的函数,这个函数用起来让人很迷糊,虽然用了半天却搞不懂他是干嘛的,说实话,研究这个函数也花了我不少的时间,期间走了不少弯路,尝试了不同的方法,从源码到出处查了好多资料,接下来我决定用通俗的语言来解释一下这个函数。
这个函数其实就是满足不同人的习惯的,为什么这么说呢?我来举一个例子,假设C语言里有一个打印手机号的标准函数printPhoneNumber(const char* phonenum)
(我杜撰的,嘿嘿),那么为了看起来更方便,可能会加一些分割符,我们知道不同的人读手机号的习惯不同,可能是是XXX-XXXX-XXXX,或者是XXXX-XXXX-XXX,还可能是XXX-XXX-XXXXX,再次假设有三个地区A、B、C,每个地区的人按一种读法来读手机号,那么为了编程方便也为了人们读起来更方便,在调用printPhoneNumber(const char* phonenum)
之前,调用os.setlocale()
来设置区域就可以按当地的习惯来显示手机号了,比如设置成区域A,打印手机号就会按XXX-XXX-XXXXX显示,是不是很方便?其实os.setlocale()
并不是用来控制手机号显示的,而是用来控制一些和人们息息相关的一些事情,比如日期显示格式,这个不同的国家不一样吧,还有货币显示,字符比较等等。
内容#
os.setlocale()##
- 原型:os.setlocale (locale [, category])
- 解释:设置程序的当前区域,函数返回设置以后该项最新的值,如果失败则返回
nil
。 - 参数:两个参数均可省略,但具体含义不同。
- locale:表示一个指定当前设置区域的字串,有几种特殊形式如下
- "":一个空字串,当前设置被视为本地设置
- "C":当前设置被视为标准C设置
- nil:返回category指示设置名的当前值
- category:一个描述要更改的设置名,实际上就是制定一个分类的名字,分类如下
- all:默认选项,包含下述所用分类。
- collate :影响C语言函数strcoll和strxfrm
- ctype:影响字符处理函数和多行字符处理函数
- monetary:影响C语言函数localeconv返回的货币格式化信息
- numeric:影响格式化输入输出字符中的小数点符号
- time:影响C语言函数strftime
Usage##
- 首先我们来新建一个文件,文件命名为setlocaletest.lua然后编写如下代码:
-- 首先查询一下初始的区域设置
print(os.setlocale(nil))
-- 设置成中文简体区域
print(os.setlocale("chs"))
-- 其实这两个是无效的,就看看返回值
print(os.setlocale("En-Us"))
print(os.setlocale("zh_CN"))
-- 设置成英文区域
print(os.setlocale("eng"))
-- 设置成中文繁体区域
print(os.setlocale("cht"))
print()
-- 现在只将数字部分设置成中文简体区域
print(os.setlocale("chs","numeric"))
-- 打印一下时间
-- 实际上现在的时间部分还是中文繁体区域
print(os.setlocale(nil,"time").."'s time format as follow:")
print(os.date("%c").."\n")
-- 现在将时间部分设置成英文区域
print(os.setlocale("eng","time"))
-- 再打印时间对比一下
print(os.setlocale(nil,"time").."'s time format as follow:")
print(os.date("%c").."\n")
-- 最后看一下当前的区域设置
print(os.setlocale(nil))
- 运行结果
总结#
- 首先来看一些结果中的第一行“C”,表明现在的区域设置是“C”,原因是当C语言程序初始化时(刚进入到 main() 时),locale 被初始化为默认的 C locale,其采用的字符编码是所有本地 ANSI 字符集编码的公共部分,是用来书写C语言源程序的最小字符集(所以才起locale名叫:C)。
- 由结果的3、4行来看当设置的区域错误时,会返回
nil
,到底可以设置哪些区域呢,下边我来列举常用的一部分:
语言缩写 | 语言种类 | 语言代码 |
---|---|---|
chs | 简体中文 | 0804 |
cht | 繁体中文 | 0404 |
jpn | 日文 | 0011 |
kor | 韩文 | 0012 |
dan | 丹麦文 | 0006 |
deu | 德文 | 0007 |
eng | 国际英文 | 0809 |
enu | 英文 | 0409 |
esp | 西班牙文 | 000A |
fin | 芬兰文 | 000B |
fra | 法文(标准) | 040C |
frc | 加拿大法文 | 0C0C |
ita | 意大利文 | 0010 |
nld | 荷兰文 | 0013 |
nor | 挪威文 | 0014 |
plk | 波兰文 | 0015 |
ptb | 巴西葡萄牙文 | 0416 |
ptg | 葡萄牙文 | 0816 |
rus | 俄文 | 0019 |
sve | 瑞典文 | 001D |
tha | 泰文 | 001E |
- 由两次显示时间格式的不同可以体现
os.setlocale()
的作用,在中文繁体区域下时间有上午和下午的区分,但是在英文区域下就没有了,而转化为了24小时的表现方法。 - 当参数locale为一个空字串,当前设置被视为本地设置,比如我在运行时就会被设置成中文简体。
- 最后我们在查询设置情况时发现,不同的分类被设置成了不同的区域,这也是符合条件的。
- 还有一点,这个函数
os.setlocale()
由于依赖了C语言函数setlocale
是线程不安全的,使用时要注意这一点。