Fix IntlExtension::formatDateTime use of date formatter prototype

This commit is contained in:
Jeroen Versteeg
2023-06-05 13:26:39 +02:00
committed by Fabien Potencier
parent 833e51ea35
commit c75762c354
2 changed files with 57 additions and 6 deletions
+17 -5
View File
@@ -370,7 +370,14 @@ final class IntlExtension extends AbstractExtension
public function formatDateTime(Environment $env, $date, ?string $dateFormat = 'medium', ?string $timeFormat = 'medium', string $pattern = '', $timezone = null, string $calendar = 'gregorian', string $locale = null): string
{
$date = twig_date_converter($env, $date, $timezone);
$formatter = $this->createDateFormatter($locale, $dateFormat, $timeFormat, $pattern, $date->getTimezone(), $calendar);
$formatterTimezone = $timezone;
if (false === $formatterTimezone) {
$formatterTimezone = $date->getTimezone();
} elseif (\is_string($formatterTimezone)) {
$formatterTimezone = new \DateTimeZone($timezone);
}
$formatter = $this->createDateFormatter($locale, $dateFormat, $timeFormat, $pattern, $formatterTimezone, $calendar);
if (false === $ret = $formatter->format($date)) {
throw new RuntimeError('Unable to format the given date.');
@@ -397,7 +404,7 @@ final class IntlExtension extends AbstractExtension
return $this->formatDateTime($env, $date, 'none', $timeFormat, $pattern, $timezone, $calendar, $locale);
}
private function createDateFormatter(?string $locale, ?string $dateFormat, ?string $timeFormat, string $pattern, \DateTimeZone $timezone, string $calendar): \IntlDateFormatter
private function createDateFormatter(?string $locale, ?string $dateFormat, ?string $timeFormat, string $pattern, ?\DateTimeZone $timezone, string $calendar): \IntlDateFormatter
{
$dateFormats = self::availableDateFormats();
@@ -410,7 +417,10 @@ final class IntlExtension extends AbstractExtension
}
if (null === $locale) {
$locale = \Locale::getDefault();
if ($this->dateFormatterPrototype) {
$locale = $this->dateFormatterPrototype->getLocale();
}
$locale = $locale ?: \Locale::getDefault();
}
$calendar = 'gregorian' === $calendar ? \IntlDateFormatter::GREGORIAN : \IntlDateFormatter::TRADITIONAL;
@@ -421,12 +431,14 @@ final class IntlExtension extends AbstractExtension
if ($this->dateFormatterPrototype) {
$dateFormatValue = $dateFormatValue ?: $this->dateFormatterPrototype->getDateType();
$timeFormatValue = $timeFormatValue ?: $this->dateFormatterPrototype->getTimeType();
$timezone = $timezone ?: $this->dateFormatterPrototype->getTimeType();
$timezone = $timezone ?: $this->dateFormatterPrototype->getTimeZone()->toDateTimeZone();
$calendar = $calendar ?: $this->dateFormatterPrototype->getCalendar();
$pattern = $pattern ?: $this->dateFormatterPrototype->getPattern();
}
$hash = $locale.'|'.$dateFormatValue.'|'.$timeFormatValue.'|'.$timezone->getName().'|'.$calendar.'|'.$pattern;
$timezoneName = $timezone ? $timezone->getName() : '(none)';
$hash = $locale.'|'.$dateFormatValue.'|'.$timeFormatValue.'|'.$timezoneName.'|'.$calendar.'|'.$pattern;
if (!isset($this->dateFormatters[$hash])) {
$this->dateFormatters[$hash] = new \IntlDateFormatter($locale, $dateFormatValue, $timeFormatValue, $timezone, $calendar, $pattern);
+40 -1
View File
@@ -12,17 +12,56 @@
namespace Twig\Extra\Intl\Tests;
use PHPUnit\Framework\TestCase;
use Twig\Environment;
use Twig\Extra\Intl\IntlExtension;
use Twig\Loader\ArrayLoader;
class IntlExtensionTest extends TestCase
{
public function testFormatterWithoutProto()
{
$ext = new IntlExtension();
$env = new Environment(new ArrayLoader());
$this->assertSame('12.346', $ext->formatNumber('12.3456'));
$this->assertSame(
'Feb 20, 2020, 1:37:00 PM',
$ext->formatDateTime($env, new \DateTime('2020-02-20T13:37:00+00:00'))
);
}
public function testFormatterProto()
{
$dateFormatterProto = new \IntlDateFormatter('fr', \IntlDateFormatter::FULL, \IntlDateFormatter::FULL);
$dateFormatterProto = new \IntlDateFormatter('fr', \IntlDateFormatter::FULL, \IntlDateFormatter::FULL, new \DateTimeZone('Europe/Paris'));
$numberFormatterProto = new \NumberFormatter('fr', \NumberFormatter::DECIMAL);
$numberFormatterProto->setTextAttribute(\NumberFormatter::POSITIVE_PREFIX, '++');
$numberFormatterProto->setAttribute(\NumberFormatter::FRACTION_DIGITS, 1);
$ext = new IntlExtension($dateFormatterProto, $numberFormatterProto);
$env = new Environment(new ArrayLoader());
$this->assertSame('++12,3', $ext->formatNumber('12.3456'));
$this->assertSame(
'jeudi 20 février 2020 à 14:37:00 heure normale dEurope centrale',
$ext->formatDateTime($env, new \DateTime('2020-02-20T13:37:00+00:00'))
);
}
public function testFormatterOverridenProto()
{
$dateFormatterProto = new \IntlDateFormatter('fr', \IntlDateFormatter::FULL, \IntlDateFormatter::FULL, new \DateTimeZone('Europe/Paris'));
$numberFormatterProto = new \NumberFormatter('fr', \NumberFormatter::DECIMAL);
$numberFormatterProto->setTextAttribute(\NumberFormatter::POSITIVE_PREFIX, '++');
$numberFormatterProto->setAttribute(\NumberFormatter::FRACTION_DIGITS, 1);
$ext = new IntlExtension($dateFormatterProto, $numberFormatterProto);
$env = new Environment(new ArrayLoader());
$this->assertSame(
'twelve point three',
$ext->formatNumber('12.3456', [], 'spellout', 'default', 'en_US')
);
$this->assertSame(
'2020-02-20 13:37:00',
$ext->formatDateTime($env, new \DateTime('2020-02-20T13:37:00+00:00'), 'short', 'short', 'yyyy-MM-dd HH:mm:ss', 'UTC', 'gregorian', 'en_US')
);
}
}