Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 17 additions & 5 deletions extra/intl-extra/IntlExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,14 @@ public function formatNumberStyle(string $style, $number, array $attrs = [], str
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.');
Expand All @@ -397,7 +404,7 @@ public function formatTime(Environment $env, $date, ?string $timeFormat = 'mediu
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();

Expand All @@ -410,7 +417,10 @@ private function createDateFormatter(?string $locale, ?string $dateFormat, ?stri
}

if (null === $locale) {
$locale = \Locale::getDefault();
if ($this->dateFormatterPrototype) {
$locale = $this->dateFormatterPrototype->getLocale();
}
$locale = $locale ?: \Locale::getDefault();
}

$calendar = 'gregorian' === $calendar ? \IntlDateFormatter::GREGORIAN : \IntlDateFormatter::TRADITIONAL;
Expand All @@ -421,12 +431,14 @@ private function createDateFormatter(?string $locale, ?string $dateFormat, ?stri
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);
Expand Down
41 changes: 40 additions & 1 deletion extra/intl-extra/Tests/IntlExtensionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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 d’Europe 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')
);
}
}