From 7215c9e5e4503502ba2aaaf376d1e94a664ff05f Mon Sep 17 00:00:00 2001 From: Quentin Schuler Date: Thu, 2 Feb 2023 09:24:56 +0100 Subject: [PATCH] Add the new PHP 8.0 IntlDateFormatter::RELATIVE_* constants for date formatting. --- IntlExtension.php | 45 +++++++++++++++++++++++----- Tests/Fixtures/format_date_php8.test | 12 ++++++++ 2 files changed, 50 insertions(+), 7 deletions(-) create mode 100644 Tests/Fixtures/format_date_php8.test diff --git a/IntlExtension.php b/IntlExtension.php index 76c2b27..955d6ec 100644 --- a/IntlExtension.php +++ b/IntlExtension.php @@ -26,7 +26,36 @@ 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 @@ public function formatTime(Environment $env, $date, ?string $timeFormat = 'mediu 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 @@ private function createDateFormatter(?string $locale, ?string $dateFormat, ?stri $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(); diff --git a/Tests/Fixtures/format_date_php8.test b/Tests/Fixtures/format_date_php8.test new file mode 100644 index 0000000..67e0e6f --- /dev/null +++ b/Tests/Fixtures/format_date_php8.test @@ -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-- +aujourd’hui +aujourd’hui à 23:39:12 temps universel coordonné