PHP currently does not provide a way to flexibly create localized date formats, even though the underlying ICU library exposes such functionality already.
For locale-specific date and time formatting, IntlDateFormatter
provides 6 options: IntlDateFormatter::LONG
, IntlDateFormatter::MEDIUM
, and IntlDateFormatter::SHORT
, with RELATIVE_
variants.
However, sometimes more flexibility is necessary.
For example, if an application requires a format that will always use the long version of a year, but the short version of a month (eg. “MM/dd/YYYY” for “en_US”, or “dd.MM.YYYY” for “de_DE”), one is out of luck.
IntlDateFormatter::SHORT
will use the short year for “de_DE” (“dd.MM.YY”), and IntlDateFormatter::MEDIUM
will use the long version of a month for “en_US” (“MMM dd, YYYY”).
Here, it would be useful to specify exactly which forms should be used (“dd”, “MM”, and “YYYY”), but leave the exact order and formatting of these components to the formatter.
This is exactly what the ICU DateTimePatternGenerator
class does. It allows generating a localized formatting pattern from a given so-called skeleton.
Add a class IntlDatePatternGenerator
that exposes the underlying ICU functionality to PHP, and allows generating formatting patterns that can be used with IntlDateFormatter
to format dates/times.
class IntlDatePatternGenerator { public function __construct(?string $locale = null) {} public static function create(?string $locale = null): ?IntlDatePatternGenerator {} public function getBestPattern(string $skeleton): string|false {} } // Procedural style: function datepatterngenerator_create(?string $locale = null): ?IntlDatePatternGenerator {} function datepatterngenerator_get_best_pattern(IntlDatePatternGenerator $patternGenerator, string $skeleton): string|false {}
With this, the use-case given above can be fulfilled:
$skeleton = "YYYYMMdd"; $today = \DateTimeImmutable::createFromFormat('Y-m-d', '2021-04-24'); $dtpg = new \IntlDatePatternGenerator("de_DE"); $pattern = $dtpg->getBestPattern($skeleton); echo "de: ", \IntlDateFormatter::formatObject($today, $pattern, "de_DE"), "\n"; $dtpg = new \IntlDatePatternGenerator("en_US"); $pattern = $dtpg->getBestPattern($skeleton), "\n"; echo "en: ", \IntlDateFormatter::formatObject($today, $pattern, "en_US"), "\n"; /* de: 24.04.2021 en: 04/24/2021 */
We have two options for naming here:
IntlDateTimePatternGenerator
:
DateTimePatternGenerator
(similar to how IntlDateFormatter
is consistent with ICU's DateFormatter
).
IntlDatePatternGenerator
IntlDateFormatter
, giving PHP more internal consistency.
IntlDatePatternGenerator
seems to be the preferred option in all counts here.
None, except that the class name IntlDatePatternGenerator
will be declared by PHP and conflict with applications declaring the same class name in the global namespace.
8.1
The ICU DateTimePatternGenerator
class provides some additional methods (for example getSkeleton
to reduce a given pattern to its skeleton form). These other methodes are of limited use compared to getBestPattern
, and have been omitted in this RFC.
Yes/No, requiring a 2/3 majority. Voting started on 2021-05-14 16:00 UTC and ends 2021-05-28 16:00 UTC.
The implementation is available at https://github.com/php/php-src/pull/6771
After the project is implemented, this section should contain
Bug report: https://bugs.php.net/bug.php?id=70377