PHP-Intl 行为与 PHP V7.0.20 不同

PHP-Intl acts different for PHP V7.0.20

我有以下代码:

$lang="de-AT";
$currency="3333";
$formatter = new NumberFormatter($lang, NumberFormatter::DECIMAL);
$formatter->setAttribute(NumberFormatter::MAX_FRACTION_DIGITS, 2);

echo $formatter->format($currency);

在这里可以是 运行 copy/paste:online php(虽然我不知道这个网站的 php 版本)

输出:3.333,这正是我所期望的。

但是在我使用 PHP 7.0.20 和 PHPUnit 6.2.1 的本地主机上,单元测试给我的结果是:3 333

知道有什么新鲜事或为什么吗?

您在此处看到的区域设置 de-AT 的差异:

3.333

3 333

只是单纯的字符串比较,有区别

对于书面语,没有。两种形式在该语言环境中都是正确的,并且显示 相同 数字。

但是,您想更明确地配置它,为此,命令数字格式化程序使用点“.”。作为千位分隔符(而不是使用编译的语言环境信息):

$formatter->setSymbol(NumberFormatter::GROUPING_SEPARATOR_SYMBOL, '.');

配置数据

根本原因是实际代码旁边的 PHP 国际扩展附带了语言数据(来自 CLDR 项目),它由符号和规则形式的格式化信息组成。这意味着,即使扩展版本相同,格式也可以更改(正如您在 Phpunit 测试中发现的那样)。派生 from your example:

  • hhvm-3.15.4 - 3.19.0、7.2.0alpha1 的输出

    3.333 1.1.0

  • 5.6.0 - 5.6.30、7.0.0 - 7.1.6 的输出

    3333 1.1.0

导致 space 而不是点的行是:

http://unicode.org/cldr/trac/browser/trunk/common/main/de_AT.xml#L120 (@13494)

具体变化:

http://unicode.org/cldr/trac/changeset/11798/trunk/common/main/de_AT.xml

以前,数字组符号是从具有点的父区域设置中接管的。

在 Changeset 11798 时间戳中:07/13/15 12:38:02(2 年前)- 发布需要时间,所以这就是为什么您只在库的后续版本中看到它。

我只能强调一点,这是配置数据。

处理(单元)测试中的配置

在单元测试中,您通常不想测试它。在配置测试中,您可能想要对此进行测试。您的 Phpunit 测试确实表明您到目前为止的期望不再匹配。因此,这可能需要更改代码(即使您的配置期望再次起作用)或更改测试,因为您正在测试特定于语言环境的配置,您可能不是您想要的。

根据你的问题,我可以想象两者都是可能的。最后,测试反映了您的期望,并且可能揭示了隐藏的依赖项,这里是语言环境配置数据。

只需将区域设置切换为“de”而不是“de-AT”即可解决问题:https://3v4l.org/hB15n

  • 5.6.0 - 5.6.30、hhvm-3.15.4 - 3.19.0、7.0.0 - 7.2.0alpha1 的输出

    3.333 1.1.0

但请记住,这也会隐藏您可能测试错误的潜在问题。因此,最好保留失败的测试作为注释,问问自己您的期望以及代码是否符合您编写的目的。