phparabicalpine-linuxicuintl

Missing Arabic numbers when formatting date using IntlDateFormatter on PHP 8.2 and newest Alpine Linux 3.19


I am trying to update my PHP project from PHP 7.4 to 8.2. I have an issue with formatting date using IntlDateFormatter class for ar_AE locale under PHP 8.2 Alpine 3.19 version. On my previous setup (PHP 7.4 Alpine 3.12) formatting date was returning whole string of Arabic characters, but under 8.2 this is not happening, in output I have Arabic letters, not numbers.

During work I have found that ICU data has been split (https://wiki.alpinelinux.org/wiki/Release_Notes_for_Alpine_3.16.0#ICU_data_split) in Linux Alpine 3.16 so I have added icu-libs and icu-data-full to 8.2 Dockerfile. This has solved my problem partially, as numbers are still not displayed in ar_AE locale.

Output for PHP 7.4:

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

Output for PHP 8.2:

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

So my question is simple, why on 8.2 PHP Alpine Linux 3.19 I still have non-Arabic numbers in output for ar_AE locale? What am I missing? Is there any other dependency that I should have install to achieve that? Maybe that is correct output and I should adjust my phpunit tests?

This is a content of test.php file which I used on both Docker images in order to test output of formatting:

<?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 to reproduce behaviour under 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

INTL version after installation:

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

Dockerfile to reproduce behaviour under 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

INTL version after installation:

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

I was also installing additional fonts, with no luck:

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

Solution

  • Considering it works in other locales but not that specific one, I suspect that locale expects latin numbers in dates. This post on the Apple developer forum confirmed my suspicion:

    Some regions prefer to use Western digits rather than Arabic-Indic digits, so you'll see this discrepancy for these locales:

    ar_AE ar_DZ ar_EH ar_LY ar_MA ar_TN

    If you really need to use ar_AE, though it's not recommended to modify the expected behavior, you can force using Arabic numbers by adding a modifier to the locale:

    ar_AE@numbers=arab