在 PHP 8.2 和最新的 Alpine Linux 3.19 上使用 IntlDateFormatter 格式化日期时缺少阿拉伯数字

use*_*883 7 php arabic icu intl alpine-linux

我正在尝试将我的 PHP 项目从 PHP 7.4 更新到 8.2。IntlDateFormatter我在使用类格式化日期时遇到问题ar_AE我在 PHP 8.2 Alpine 3.19 版本下使用区域在我之前的设置(PHP 7.4 Alpine 3.12)中,格式化日期返回整个阿拉伯字符字符串,但在 8.2 下,这种情况不会发生,在输出中我有阿拉伯字母,而不是数字。

\n

在工作期间,我发现 ICU 数据已在 Linux Alpine 3.16 中拆分( https://wiki.alpinelinux.org/wiki/Release_Notes_for_Alpine_3.16.0#ICU_data_spliticu-libs ),因此我已将和添加icu-data-full到 8.2 Dockerfile 中。这部分解决了我的问题,因为数字仍然没有显示在ar_AE区域设置中显示。

\n

PHP 7.4 的输出:

\n
/var/www $ php test.php\nar_AE: \xd8\xa7\xd9\x84\xd8\xb3\xd8\xa8\xd8\xaa\xd8\x8c \xd9\xa1 \xd9\x8a\xd9\x86\xd8\xa7\xd9\x8a\xd8\xb1 \xd9\xa2\xd9\xa0\xd9\xa2\xd9\xa2 \xd9\xa1\xd9\xa2:\xd9\xa5\xd9\xa9:\xd9\xa5\xd9\xa9 \xd8\xb5 \xd8\xaa\xd9\x88\xd9\x82\xd9\x8a\xd8\xaa \xd9\x88\xd8\xb3\xd8\xb7 \xd8\xa3\xd9\x88\xd8\xb1\xd9\x88\xd8\xa8\xd8\xa7 \xd8\xa7\xd9\x84\xd8\xb1\xd8\xb3\xd9\x85\xd9\x8a\nar_QA: \xd8\xa7\xd9\x84\xd8\xb3\xd8\xa8\xd8\xaa\xd8\x8c \xd9\xa1 \xd9\x8a\xd9\x86\xd8\xa7\xd9\x8a\xd8\xb1 \xd9\xa2\xd9\xa0\xd9\xa2\xd9\xa2 \xd9\xa1\xd9\xa2:\xd9\xa5\xd9\xa9:\xd9\xa5\xd9\xa9 \xd8\xb5 \xd8\xaa\xd9\x88\xd9\x82\xd9\x8a\xd8\xaa \xd9\x88\xd8\xb3\xd8\xb7 \xd8\xa3\xd9\x88\xd8\xb1\xd9\x88\xd8\xa8\xd8\xa7 \xd8\xa7\xd9\x84\xd8\xb1\xd8\xb3\xd9\x85\xd9\x8a\nar_SA: \xd8\xa7\xd9\x84\xd8\xb3\xd8\xa8\xd8\xaa\xd8\x8c \xd9\xa1 \xd9\x8a\xd9\x86\xd8\xa7\xd9\x8a\xd8\xb1 \xd9\xa2\xd9\xa0\xd9\xa2\xd9\xa2 \xd9\x85 \xd9\xa1\xd9\xa2:\xd9\xa5\xd9\xa9:\xd9\xa5\xd9\xa9 \xd8\xb5 \xd8\xaa\xd9\x88\xd9\x82\xd9\x8a\xd8\xaa \xd9\x88\xd8\xb3\xd8\xb7 \xd8\xa3\xd9\x88\xd8\xb1\xd9\x88\xd8\xa8\xd8\xa7 \xd8\xa7\xd9\x84\xd8\xb1\xd8\xb3\xd9\x85\xd9\x8a\n
Run Code Online (Sandbox Code Playgroud)\n

PHP 8.2 的输出:

\n
/var/www $ php test.php\nar_AE: \xd8\xa7\xd9\x84\xd8\xb3\xd8\xa8\xd8\xaa\xd8\x8c 1 \xd9\x8a\xd9\x86\xd8\xa7\xd9\x8a\xd8\xb1 2022 \xd9\x81\xd9\x8a 12:59:59 \xd8\xb5 \xd8\xaa\xd9\x88\xd9\x82\xd9\x8a\xd8\xaa \xd9\x88\xd8\xb3\xd8\xb7 \xd8\xa3\xd9\x88\xd8\xb1\xd9\x88\xd8\xa8\xd8\xa7 \xd8\xa7\xd9\x84\xd8\xb1\xd8\xb3\xd9\x85\xd9\x8a\nar_QA: \xd8\xa7\xd9\x84\xd8\xb3\xd8\xa8\xd8\xaa\xd8\x8c \xd9\xa1 \xd9\x8a\xd9\x86\xd8\xa7\xd9\x8a\xd8\xb1 \xd9\xa2\xd9\xa0\xd9\xa2\xd9\xa2 \xd9\x81\xd9\x8a \xd9\xa1\xd9\xa2:\xd9\xa5\xd9\xa9:\xd9\xa5\xd9\xa9 \xd8\xb5 \xd8\xaa\xd9\x88\xd9\x82\xd9\x8a\xd8\xaa \xd9\x88\xd8\xb3\xd8\xb7 \xd8\xa3\xd9\x88\xd8\xb1\xd9\x88\xd8\xa8\xd8\xa7 \xd8\xa7\xd9\x84\xd8\xb1\xd8\xb3\xd9\x85\xd9\x8a\nar_SA: \xd8\xa7\xd9\x84\xd8\xb3\xd8\xa8\xd8\xaa\xd8\x8c \xd9\xa1 \xd9\x8a\xd9\x86\xd8\xa7\xd9\x8a\xd8\xb1 \xd9\xa2\xd9\xa0\xd9\xa2\xd9\xa2 \xd9\x85 \xd9\x81\xd9\x8a \xd9\xa1\xd9\xa2:\xd9\xa5\xd9\xa9:\xd9\xa5\xd9\xa9 \xd8\xb5 \xd8\xaa\xd9\x88\xd9\x82\xd9\x8a\xd8\xaa \xd9\x88\xd8\xb3\xd8\xb7 \xd8\xa3\xd9\x88\xd8\xb1\xd9\x88\xd8\xa8\xd8\xa7 \xd8\xa7\xd9\x84\xd8\xb1\xd8\xb3\xd9\x85\xd9\x8a\n
Run Code Online (Sandbox Code Playgroud)\n

所以我的问题很简单,为什么在 8.2 PHP Alpine Linux 3.19 上,区域设置的输出中仍然有非阿拉伯数字ar_AE?我缺少什么?我是否应该安装任何其他依赖项才能实现此目的?也许这是正确的输出,我应该调整我的 phpunit 测试?

\n

这是我在两个 Docker 映像上使用的文件内容test.php,以测试格式化输出:

\n
<?php\n\n$formatter = new IntlDateFormatter(\n    \'ar_AE\',\n    IntlDateFormatter::FULL,\n    IntlDateFormatter::FULL,\n    \'Europe/Berlin\'\n);\n\necho \'ar_AE: \' . $formatter->format(new DateTime(\'2021-12-31 23:59:59\'));\necho PHP_EOL;\n\n$formatter = new IntlDateFormatter(\n    \'ar_QA\',\n    IntlDateFormatter::FULL,\n    IntlDateFormatter::FULL,\n    \'Europe/Berlin\'\n);\n\necho \'ar_QA: \' . $formatter->format(new DateTime(\'2021-12-31 23:59:59\'));\necho PHP_EOL;\n\n$formatter = new IntlDateFormatter(\n    \'ar_SA\',\n    IntlDateFormatter::FULL,\n    IntlDateFormatter::FULL,\n    \'Europe/Berlin\'\n);\n\necho \'ar_SA: \' . $formatter->format(new DateTime(\'2021-12-31 23:59:59\'));\necho PHP_EOL;\n
Run Code Online (Sandbox Code Playgroud)\n

Dockerfile 重现 7.4 下的行为:

\n
FROM php:7.4-fpm-alpine3.12\n\nRUN apk update \\\n    && apk --no-cache add \\\n    freetype  \\\n    icu \\\n    icu-dev\n\nRUN docker-php-ext-install intl\n\nUSER www-data\nWORKDIR /var/www\n
Run Code Online (Sandbox Code Playgroud)\n

安装后的INTL版本:

\n
Internationalization support => enabled\nICU version => 67.1\nICU Data version => 67.1\nICU TZData version => 2019c\nICU Unicode version => 13.0\n
Run Code Online (Sandbox Code Playgroud)\n

在 8.2 下重现行为的 Dockerfile:

\n
FROM php:8.2-fpm-alpine3.19\n\nRUN apk update \\\n    && apk --no-cache add \\\n    freetype  \\\n    icu \\\n    icu-dev \\\n    icu-libs \\\n    icu-data \\\n    icu-data-full\n\nRUN docker-php-ext-install intl\n\nUSER www-data\nWORKDIR /var/www\n
Run Code Online (Sandbox Code Playgroud)\n

安装后的INTL版本:

\n
Internationalization support => enabled\nICU version => 74.1\nICU Data version => 74.1\nICU TZData version => 2023c\nICU Unicode version => 15.1\n
Run Code Online (Sandbox Code Playgroud)\n

我还安装了额外的字体,但没有成功:

\n
font-arabic-misc \\\nfont-noto-arabic \\\nmusl-locales \\\nfontconfig \\\nttf-dejavu \\\nfont-noto font-noto-extra font-arabic-misc \\\nfont-misc-cyrillic font-mutt-misc font-screen-cyrillic font-winitzki-cyrillic font-cronyx-cyrillic \\\nfont-noto-armenian font-noto-cherokee font-noto-devanagari font-noto-ethiopic font-noto-georgian \\\nfont-noto-hebrew font-noto-lao font-noto-malayalam font-noto-tamil font-noto-thaana font-noto-thai \\\nfreetype ttf-droid ttf-freefont ttf-liberation freetype-dev\n
Run Code Online (Sandbox Code Playgroud)\n

Jim*_*Jim 3

考虑到它适用于其他语言环境,但不适用于特定的语言环境,我怀疑该语言环境需要日期中的拉丁数字。苹果开发者论坛上的这篇文章证实了我的怀疑:

某些地区更喜欢使用西方数字而不是阿拉伯-印度数字,因此您会看到这些区域设置的差异:

ar_AE ar_DZ ar_EH ar_LY ar_MA ar_TN

如果您确实需要使用 ar_AE,尽管不建议修改预期行为,但您可以通过向区域设置添加修饰符来强制使用阿拉伯数字:

ar_AE@numbers=arab