From 2856abe87f1086bfa563c770447cbd2d7c7875e0 Mon Sep 17 00:00:00 2001 From: Christophe Coevoet Date: Fri, 7 Aug 2015 15:14:23 +0200 Subject: [PATCH] Implement the support of timezone objects in the stub IntlDateFormatter As of PHP 5.5, the IntlDateFormatter accepts to use DateTimeZone or IntlTimeZone objects as timezone in the constructor (and in the new setTimeZone method) rather than timezone ids. This is even the proper way to pass a timezone from a DateTime object as DateTimeZone names are not all valid ICU identifiers. --- .../Intl/DateFormatter/IntlDateFormatter.php | 17 +++++++++-- .../AbstractIntlDateFormatterTest.php | 30 +++++++++++++++++++ 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/Intl/DateFormatter/IntlDateFormatter.php b/src/Symfony/Component/Intl/DateFormatter/IntlDateFormatter.php index f08ed8d8ed..3e0ac5de17 100644 --- a/src/Symfony/Component/Intl/DateFormatter/IntlDateFormatter.php +++ b/src/Symfony/Component/Intl/DateFormatter/IntlDateFormatter.php @@ -132,7 +132,7 @@ class IntlDateFormatter * @param string $locale The locale code. The only currently supported locale is "en" (or null using the default locale, i.e. "en"). * @param int $datetype Type of date formatting, one of the format type constants * @param int $timetype Type of time formatting, one of the format type constants - * @param string $timezone Timezone identifier + * @param mixed $timezone Timezone identifier * @param int $calendar Calendar to use for formatting or parsing. The only currently * supported value is IntlDateFormatter::GREGORIAN. * @param string $pattern Optional pattern to use when formatting @@ -157,7 +157,7 @@ class IntlDateFormatter $this->timetype = $timetype; $this->setPattern($pattern); - $this->setTimeZoneId($timezone); + $this->setTimeZone($timezone); } /** @@ -588,6 +588,19 @@ class IntlDateFormatter */ public function setTimeZone($timeZone) { + if ($timeZone instanceof \IntlTimeZone) { + $timeZone = $timeZone->getID(); + } + + if ($timeZone instanceof \DateTimeZone) { + $timeZone = $timeZone->getName(); + + // DateTimeZone returns the GMT offset timezones without the leading GMT, while our parsing requires it. + if (!empty($timeZone) && ('+' === $timeZone[0] || '-' === $timeZone[0])) { + $timeZone = 'GMT'.$timeZone; + } + } + return $this->setTimeZoneId($timeZone); } diff --git a/src/Symfony/Component/Intl/Tests/DateFormatter/AbstractIntlDateFormatterTest.php b/src/Symfony/Component/Intl/Tests/DateFormatter/AbstractIntlDateFormatterTest.php index 71ef473960..c17dca13fd 100644 --- a/src/Symfony/Component/Intl/Tests/DateFormatter/AbstractIntlDateFormatterTest.php +++ b/src/Symfony/Component/Intl/Tests/DateFormatter/AbstractIntlDateFormatterTest.php @@ -387,6 +387,36 @@ abstract class AbstractIntlDateFormatterTest extends \PHPUnit_Framework_TestCase ); } + public function testFormatWithDateTimeZone() + { + if (PHP_VERSION_ID < 50500) { + $this->markTestSkipped('Only in PHP 5.5+ IntlDateFormatter allows to use DateTimeZone objects.'); + } + + if (defined('HHVM_VERSION_ID')) { + $this->markTestSkipped('This test cannot work on HHVM. See https://github.com/facebook/hhvm/issues/5875 for the issue.'); + } + + $formatter = $this->getDateFormatter('en', IntlDateFormatter::MEDIUM, IntlDateFormatter::SHORT, new \DateTimeZone('GMT+03:00'), IntlDateFormatter::GREGORIAN, 'zzzz'); + + $this->assertEquals('GMT+03:00', $formatter->format(0)); + } + + public function testFormatWithIntlTimeZone() + { + if (PHP_VERSION_ID < 50500) { + $this->markTestSkipped('Only in PHP 5.5+ IntlDateFormatter allows to use DateTimeZone objects.'); + } + + if (!class_exists('IntlTimeZone')) { + $this->markTestSkipped('This test requires the IntlTimeZone class from the Intl extension.'); + } + + $formatter = $this->getDateFormatter('en', IntlDateFormatter::MEDIUM, IntlDateFormatter::SHORT, \IntlTimeZone::createTimeZone('GMT+03:00'), IntlDateFormatter::GREGORIAN, 'zzzz'); + + $this->assertEquals('GMT+03:00', $formatter->format(0)); + } + public function testFormatWithTimezoneFromEnvironmentVariable() { if (PHP_VERSION_ID >= 50500) {