服务器信息(已删除 DNS 和 IP):
cat /proc/version && uname -a && java -version
Linux version 2.6.16.33-xenU (*************) (gcc version 4.1.1 20070105 (Red Hat 4.1.1-52)) #2 SMP Wed Aug 15 17:27:36 SAST 2007
Linux ************* *************-xenU #2 SMP Wed Aug 15 17:27:36 SAST 2007 x86_64 x86_64 x86_64 GNU/Linux
java version "1.6.0_14"
Java(TM) SE Runtime Environment (build 1.6.0_14-b08)
Java HotSpot(TM) 64-Bit Server VM (build 14.0-b16, mixed mode)
我有一些 PHP 代码,用于读取 Excel 文件并进行字符串比较。由于似乎是区域设置问题,它在服务器上失败了。但是在我的本地机器 (OSX 10.8.5 Mountain Lion) 上,它可以正常工作!
在我的本地机器上,语言环境是 en_US.UTF-8。在服务器上,语言环境是 POSIX,但我将其更改为 en_US.utf8,因为当我查看时没有 en_US.UTF-8区域设置-a(有趣的是,服务器上的语言环境列表都是小写的,但在我的 Mac 上它们都是大写的,这就是这个问题的根源)。
两者之间是否存在差异,从而影响字符串比较?
此外,根据这篇 SF 帖子我跑了区域设置-v-a。在服务器上,en-US.utf8 使用 UTF-8 代码集(我假设这与我通常所说的字符集相同?)。但是,在我的本地机器上,我似乎无法运行区域设置-v-a命令,但是区域设置和区域设置-a工作正常。
答案1
总结:
据我所知,代码页/字符集.utf8
未被en_US.utf8
官方认可。没有 IANAutf8
字符集姓名.utf8
可能是由glibc
- 参见最后的标题生成的。
IANA 字符集名称是UTF-8
。
- 连字符很重要
- 案例是在敏感的
因此,这些都是有效的:
en_US.utf-8
en_US.UTF-8
en_US.uTf-8
还有一个!区分大小写!别名为了姓名 UTF-8
,即:csUTF8
。
因此,这也是有效的:
en_US.csUTF8
但我从未在野外见过这种情况。
细节,有章节和诗句
UTF-8
是有效的 IANA 字符集姓名,而utf8
不是。它甚至不是一个有效的别名。
POSIX.1-2017,部分8.2 国际化变量说:
如果语言环境值的形式如下:
language[_territory][.codeset]
它指的是实现提供的区域设置,其中语言、地区和代码集的设置是由实现定义的。
这里所讨论的部分是[.codeset]
POSIX 未定义但 IANA 定义的部分。
对于 RFC2978 定义的字符集UTF-8, a transformation format of ISO 10646
:
IANA 字符集列出姓名作为:
UTF-8
顶部的注释写道:
这些是可在互联网中使用并可在互联网文档中引用的字符集的正式名称。
一个别名 csUTF8
提供关于RFC2978 IANA 字符集注册程序,第 2.3 节说:
所有其他名称都被视为主要名称的别名,并且使用主要名称的优先于使用任何别名。
IANA 字符集还说:
“cs”代表字符集,适用于需要首字母小写但此后使用混合大小写且不能包含任何特殊字符(如下划线(“_”)和破折号(“-”))的应用程序。
在cs
别名中,大小写很重要(而上面将名称定义为不区分大小写)。
给定别名csUTF8
,en_US.csUTF8
也是有效的,但我从未在野外见过这种格式。
虽然大小写很重要别名, 关于名称,IANA 字符集说:
字符集名称最多可包含 40 个字符,这些字符取自 US-ASCII 的可打印字符。但是,大小写字母的使用没有区别。
因此,虽然en_US.utf-8
是有效的(列出的 的小写版本UTF-8
),en_US.utf8
但并不指 IANA 字符集,因为它删除了-
。
如果不是 IANA,那么utf8
可能来自哪里?
glibc 的_nl_normalize_codeset()
执行以下操作:
仅传递字符或数字(告别连字符)
将字符转换为小写
for (cnt = 0; cnt < name_len; ++cnt) if (__isalpha_l ((unsigned char) codeset[cnt], locale)) *wp++ = __tolower_l ((unsigned char) codeset[cnt], locale); else if (__isdigit_l ((unsigned char) codeset[cnt], locale)) *wp++ = codeset[cnt];
答案2
没有区别。它们是同一个东西。