Add the new PHP 8.0 IntlDateFormatter::RELATIVE_* constants for date formatting.

This commit is contained in:
Quentin Schuler
2023-02-02 09:24:56 +01:00
parent 609794c376
commit 5776f76068
3 changed files with 56 additions and 7 deletions
+6
View File
@@ -26,6 +26,12 @@ You can tweak the output for the date part and the time part:
Supported values are: ``none``, ``short``, ``medium``, ``long``, and ``full``.
.. versionadded:: 3.6
``relative_short``, ``relative_medium``, ``relative_long``, and ``relative_full`` are also supported when running on
PHP 8.0 and superior or when using a polyfill that define the ``IntlDateFormatter::RELATIVE_*`` constants and
associated behavior.
For greater flexibility, you can even define your own pattern
(see the `ICU user guide`_ for supported patterns).
+38 -7
View File
@@ -26,7 +26,36 @@ use Twig\TwigFunction;
final class IntlExtension extends AbstractExtension
{
private const DATE_FORMATS = [
private static function availableDateFormats(): array
{
static $formats = null;
if (null !== $formats) {
return $formats;
}
$formats = [
'none' => \IntlDateFormatter::NONE,
'short' => \IntlDateFormatter::SHORT,
'medium' => \IntlDateFormatter::MEDIUM,
'long' => \IntlDateFormatter::LONG,
'full' => \IntlDateFormatter::FULL,
];
// Assuming that each `RELATIVE_*` constant are defined when one of them is.
if (\defined('IntlDateFormatter::RELATIVE_FULL')) {
$formats = array_merge($formats, [
'relative_short' => \IntlDateFormatter::RELATIVE_SHORT,
'relative_medium' => \IntlDateFormatter::RELATIVE_MEDIUM,
'relative_long' => \IntlDateFormatter::RELATIVE_LONG,
'relative_full' => \IntlDateFormatter::RELATIVE_FULL,
]);
}
return $formats;
}
private const TIME_FORMATS = [
'none' => \IntlDateFormatter::NONE,
'short' => \IntlDateFormatter::SHORT,
'medium' => \IntlDateFormatter::MEDIUM,
@@ -370,12 +399,14 @@ final class IntlExtension extends AbstractExtension
private function createDateFormatter(?string $locale, ?string $dateFormat, ?string $timeFormat, string $pattern, \DateTimeZone $timezone, string $calendar): \IntlDateFormatter
{
if (null !== $dateFormat && !isset(self::DATE_FORMATS[$dateFormat])) {
throw new RuntimeError(sprintf('The date format "%s" does not exist, known formats are: "%s".', $dateFormat, implode('", "', array_keys(self::DATE_FORMATS))));
$dateFormats = self::availableDateFormats();
if (null !== $dateFormat && !isset($dateFormats[$dateFormat])) {
throw new RuntimeError(sprintf('The date format "%s" does not exist, known formats are: "%s".', $dateFormat, implode('", "', array_keys($dateFormats))));
}
if (null !== $timeFormat && !isset(self::DATE_FORMATS[$timeFormat])) {
throw new RuntimeError(sprintf('The time format "%s" does not exist, known formats are: "%s".', $timeFormat, implode('", "', array_keys(self::DATE_FORMATS))));
if (null !== $timeFormat && !isset(self::TIME_FORMATS[$timeFormat])) {
throw new RuntimeError(sprintf('The time format "%s" does not exist, known formats are: "%s".', $timeFormat, implode('", "', array_keys(self::TIME_FORMATS))));
}
if (null === $locale) {
@@ -384,8 +415,8 @@ final class IntlExtension extends AbstractExtension
$calendar = 'gregorian' === $calendar ? \IntlDateFormatter::GREGORIAN : \IntlDateFormatter::TRADITIONAL;
$dateFormatValue = self::DATE_FORMATS[$dateFormat] ?? null;
$timeFormatValue = self::DATE_FORMATS[$timeFormat] ?? null;
$dateFormatValue = $dateFormats[$dateFormat] ?? null;
$timeFormatValue = self::TIME_FORMATS[$timeFormat] ?? null;
if ($this->dateFormatterPrototype) {
$dateFormatValue = $dateFormatValue ?: $this->dateFormatterPrototype->getDateType();
@@ -0,0 +1,12 @@
--TEST--
"format_date" filter
--CONDITION--
PHP_VERSION_ID >= 80000
--TEMPLATE--
{{ 'today 23:39:12'|format_datetime('relative_short', 'none', locale='fr') }}
{{ 'today 23:39:12'|format_datetime('relative_full', 'full', locale='fr') }}
--DATA--
return [];
--EXPECT--
aujourdhui
aujourdhui à 23:39:12 temps universel coordonné