我试图使用intl包中的NumberFormatter类将整数量拼写成斯洛文尼亚语单词(用于邮政声明),但结果是完全错误的,没有任何意义.
$fmt = new NumberFormatter('sl', NumberFormatter::SPELLOUT);
$fmt->format(561);
Run Code Online (Sandbox Code Playgroud)
结果在"petstošestdesetena",而它应该是"petstoenainšestdeset".看起来像宝贝说话.
用克罗地亚语非常相似,结果似乎没问题("petstošezdesetijedan").
这是PHP中翻译得不好的,还是基于我的系统区域设置?我在PHP 5.3.10/Ubuntu 12.04上.
编辑:
intl是版本1.1.0,当前是3.0.0,所以它可能已修复?
免责声明 - 我不会说斯洛文尼亚语或克罗地亚语.
看起来PHP扩展用于这些语言中的数字的模式存在一些差距.要查看我的意思,您可以显示运行使用的模式:
$fmt = new NumberFormatter('sl', NumberFormatter::SPELLOUT);
echo $fmt->getPattern();
Run Code Online (Sandbox Code Playgroud)
如果你看一下这个的输出,你可能会发现"%spellout-cardinal-masculine:"的一部分似乎从大约30跳到100.
...
21: dvaset >%spellout-cardinal-masculine>;
30: <%spellout-cardinal-masculine<deset;
31: <%spellout-cardinal-masculine<deset >%spellout-cardinal-masculine>;
100: sto;
101: sto >%spellout-cardinal-masculine>;
200: dvjesto;
...
Run Code Online (Sandbox Code Playgroud)
这意味着没有为31以上和100以下的数字定义规则.您输出的数字的'61'部分属于此差距.
你可以生成自己的模式来解决这个问题 - 我粘贴在en-US格式化程序的模式中并稍微摆弄它所以它看起来像这样:
...
21: dvaset >%spellout-cardinal-masculine>;
30: <%spellout-cardinal-masculine<deset;
31: <%spellout-cardinal-masculine<deset >%spellout-cardinal-masculine>;
40: forty;
41: forty->%spellout-cardinal-masculine>;
50: fifty;
51: fifty->%spellout-cardinal-masculine>;
60: sixty;
61: sixty->%spellout-cardinal-masculine>;
70: seventy;
71: seventy->%spellout-cardinal-masculine>;
80: eighty;
81: eighty->%spellout-cardinal-masculine>;
90: ninety;
91: ninety->%spellout-cardinal-masculine>;
100: sto;
101: sto >%spellout-cardinal-masculine>;
200: dvjesto;
...
Run Code Online (Sandbox Code Playgroud)
现在,如果我将其保存在一个名为sl.txt且使用UTF-8编码的新文件中,我可以将其加载到NumberFormatter中:
$pattern = file_get_contents('sl.txt')
$fmt = new NumberFormatter('sl', NumberFormatter::PATTERN_RULEBASED, $pattern);
echo($fmt->format(561));
Run Code Online (Sandbox Code Playgroud)
这给了我以下输出:
petsto sixty-ena
Run Code Online (Sandbox Code Playgroud)
当然这是错的 - 它是斯洛文尼亚语和英语的混合体,但我认为如果您将格式编辑为这样:
...
61: >%spellout-cardinal-masculine>inšestdeset;
...
Run Code Online (Sandbox Code Playgroud)
正如我所说,我不会说斯洛文尼亚语,所以你可能想检查它.但是这会给你以下输出:
petsto enainšestdeset
Run Code Online (Sandbox Code Playgroud)
您需要为31-100中的每个缺失数字块添加此规则.您可能还需要检查ICU文档以获取基于规则的格式,以确保正确无误.
这是一个错误,但在PHP中却没有 - 如果您想修复它,那么问题就出在此文件中Unicode的Common Locale Data Repository中.PHP的intl使用ICU,它使用CLDR数据.