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

问题描述 投票:0回答:1

我正在尝试将我的 PHP 项目从 PHP 7.4 更新到 8.2。我在 PHP 8.2 Alpine 3.19 版本下使用

IntlDateFormatter
语言环境的
ar_AE
类格式化日期时遇到问题。在我之前的设置(PHP 7.4 Alpine 3.12)中,格式化日期返回整个阿拉伯字符字符串,但在 8.2 下,这种情况不会发生,在输出中我有阿拉伯字母,而不是数字。

在工作期间,我发现 ICU 数据在 Linux Alpine 3.16 中已被拆分(https://wiki.alpinelinux.org/wiki/Release_Notes_for_Alpine_3.16.0#ICU_data_split),因此我在 8.2 中添加了

icu-libs
icu-data-full
Dockerfile。这部分解决了我的问题,因为数字仍然没有在
ar_AE
语言环境中显示。

PHP 7.4 的输出:

/var/www $ php test.php
ar_AE: السبت، ١ يناير ٢٠٢٢ ١٢:٥٩:٥٩ ص توقيت وسط أوروبا الرسمي
ar_QA: السبت، ١ يناير ٢٠٢٢ ١٢:٥٩:٥٩ ص توقيت وسط أوروبا الرسمي
ar_SA: السبت، ١ يناير ٢٠٢٢ م ١٢:٥٩:٥٩ ص توقيت وسط أوروبا الرسمي

PHP 8.2 的输出:

/var/www $ php test.php
ar_AE: السبت، 1 يناير 2022 في 12:59:59 ص توقيت وسط أوروبا الرسمي
ar_QA: السبت، ١ يناير ٢٠٢٢ في ١٢:٥٩:٥٩ ص توقيت وسط أوروبا الرسمي
ar_SA: السبت، ١ يناير ٢٠٢٢ م في ١٢:٥٩:٥٩ ص توقيت وسط أوروبا الرسمي

所以我的问题很简单,为什么在 8.2 PHP Alpine Linux 3.19 上,

ar_AE
语言环境的输出中仍然有非阿拉伯数字?我缺少什么?我是否应该安装任何其他依赖项才能实现此目的?也许这是正确的输出,我应该调整我的 phpunit 测试?

这是

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

<?php

$formatter = new IntlDateFormatter(
    'ar_AE',
    IntlDateFormatter::FULL,
    IntlDateFormatter::FULL,
    'Europe/Berlin'
);

echo 'ar_AE: ' . $formatter->format(new DateTime('2021-12-31 23:59:59'));
echo PHP_EOL;

$formatter = new IntlDateFormatter(
    'ar_QA',
    IntlDateFormatter::FULL,
    IntlDateFormatter::FULL,
    'Europe/Berlin'
);

echo 'ar_QA: ' . $formatter->format(new DateTime('2021-12-31 23:59:59'));
echo PHP_EOL;

$formatter = new IntlDateFormatter(
    'ar_SA',
    IntlDateFormatter::FULL,
    IntlDateFormatter::FULL,
    'Europe/Berlin'
);

echo 'ar_SA: ' . $formatter->format(new DateTime('2021-12-31 23:59:59'));
echo PHP_EOL;

Dockerfile 重现 7.4 下的行为:

FROM php:7.4-fpm-alpine3.12

RUN apk update \
    && apk --no-cache add \
    freetype  \
    icu \
    icu-dev

RUN docker-php-ext-install intl

USER www-data
WORKDIR /var/www

安装后国际版:

Internationalization support => enabled
ICU version => 67.1
ICU Data version => 67.1
ICU TZData version => 2019c
ICU Unicode version => 13.0

Dockerfile 重现 8.2 下的行为:

FROM php:8.2-fpm-alpine3.19

RUN apk update \
    && apk --no-cache add \
    freetype  \
    icu \
    icu-dev \
    icu-libs \
    icu-data \
    icu-data-full

RUN docker-php-ext-install intl

USER www-data
WORKDIR /var/www

安装后国际版:

Internationalization support => enabled
ICU version => 74.1
ICU Data version => 74.1
ICU TZData version => 2023c
ICU Unicode version => 15.1

我还安装了额外的字体,但没有运气:

font-arabic-misc \
font-noto-arabic \
musl-locales \
fontconfig \
ttf-dejavu \
font-noto font-noto-extra font-arabic-misc \
font-misc-cyrillic font-mutt-misc font-screen-cyrillic font-winitzki-cyrillic font-cronyx-cyrillic \
font-noto-armenian font-noto-cherokee font-noto-devanagari font-noto-ethiopic font-noto-georgian \
font-noto-hebrew font-noto-lao font-noto-malayalam font-noto-tamil font-noto-thaana font-noto-thai \
freetype ttf-droid ttf-freefont ttf-liberation freetype-dev
php arabic alpine-linux icu intl
1个回答
0
投票

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

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

ar_AE ar_DZ ar_EH ar_LY ar_MA ar_TN

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

ar_AE@numbers=arabic

不幸的是,我的测试表明由于可能存在错误,这不起作用:

Fatal error: Uncaught IntlException: datefmt_create: date formatter creation failed: U_MEMORY_ALLOCATION_ERROR

即使我使用语言环境也会发生同样的错误

ar-u-nu-arabic
。但是,其他编号系统可以正常工作。

我在这里提交了错误报告:https://github.com/php/php-src/issues/13434

不幸的是,在错误修复之前您可能无法使用此解决方法。

© www.soinside.com 2019 - 2024. All rights reserved.