Kaynağa Gözat

[Locale] refactor to use DateTime and DateTimeZone, adding timezone support

Igor Wiedler 14 yıl önce
ebeveyn
işleme
d68c5fa7fd

+ 27 - 18
src/Symfony/Component/Locale/Stub/StubIntlDateFormatter.php

@@ -29,6 +29,9 @@ class StubIntlDateFormatter
     const TRADITIONAL = 0;
     const GREGORIAN = 1;
 
+    private $pattern;
+    private $dateTimeZone;
+
     public function __construct($locale, $datetype, $timetype, $timezone = null, $calendar = null, $pattern = null)
     {
         if ('en' != $locale) {
@@ -36,10 +39,16 @@ class StubIntlDateFormatter
         }
 
         $this->setPattern($pattern);
+
+        $this->dateTimeZone = new \DateTimeZone($timezone);
     }
 
     public function format($timestamp)
     {
+        $dateTime = new \DateTime();
+        $dateTime->setTimestamp($timestamp);
+        $dateTime->setTimezone($this->dateTimeZone);
+
         $specialChars = 'MLydGQqhDEaHkKms';
         $specialCharsArray = str_split($specialChars);
         $specialCharsMatch = implode('|', array_map(function($char) {
@@ -47,7 +56,7 @@ class StubIntlDateFormatter
         }, $specialCharsArray));
         $regExp = "/('($specialCharsMatch|[^$specialChars])|$specialCharsMatch)/";
 
-        $callback = function($matches) use ($timestamp) {
+        $callback = function($matches) use ($dateTime) {
             $pattern = $matches[0];
             $length = strlen($pattern);
 
@@ -66,11 +75,11 @@ class StubIntlDateFormatter
                     );
 
                     if (isset($matchLengthMap[$length])) {
-                       return gmdate($matchLengthMap[$length], $timestamp);
+                       return $dateTime->format($matchLengthMap[$length]);
                     } else if (5 == $length) {
-                        return substr(gmdate('M', $timestamp), 0, 1);
+                        return substr($dateTime->format('M'), 0, 1);
                     } else {
-                        return str_pad(gmdate('m', $timestamp), $length, '0', STR_PAD_LEFT);
+                        return str_pad($dateTime->format('m'), $length, '0', STR_PAD_LEFT);
                     }
                     break;
 
@@ -83,24 +92,24 @@ class StubIntlDateFormatter
                     );
 
                     if (isset($matchLengthMap[$length])) {
-                       return gmdate($matchLengthMap[$length], $timestamp);
+                       return $dateTime->format($matchLengthMap[$length]);
                     } else {
-                        return str_pad(gmdate('Y', $timestamp), $length, '0', STR_PAD_LEFT);
+                        return str_pad($dateTime->format('Y'), $length, '0', STR_PAD_LEFT);
                     }
                     break;
 
                 case 'd':
-                    return str_pad(gmdate('j', $timestamp), $length, '0', STR_PAD_LEFT);
+                    return str_pad($dateTime->format('j'), $length, '0', STR_PAD_LEFT);
                     break;
 
                 case 'G':
-                    $year = (int) gmdate('Y', $timestamp);
+                    $year = (int) $dateTime->format('Y');
                     return $year >= 0 ? 'AD' : 'BC';
                     break;
 
                 case 'q':
                 case 'Q':
-                    $month = (int) gmdate('n', $timestamp);
+                    $month = (int) $dateTime->format('n');
                     $quarter = (int) floor(($month - 1) / 3) + 1;
                     switch ($length) {
                         case 1:
@@ -118,16 +127,16 @@ class StubIntlDateFormatter
                     break;
 
                 case 'h':
-                    return str_pad(gmdate('g', $timestamp), $length, '0', STR_PAD_LEFT);
+                    return str_pad($dateTime->format('g'), $length, '0', STR_PAD_LEFT);
                     break;
 
                 case 'D':
-                    $dayOfYear = gmdate('z', $timestamp) + 1;
+                    $dayOfYear = $dateTime->format('z') + 1;
                     return str_pad($dayOfYear, $length, '0', STR_PAD_LEFT);
                     break;
 
                 case 'E':
-                    $dayOfWeek = gmdate('l', $timestamp);
+                    $dayOfWeek = $dateTime->format('l');
                     switch ($length) {
                         case 4:
                             return $dayOfWeek;
@@ -141,32 +150,32 @@ class StubIntlDateFormatter
                     break;
 
                 case 'a':
-                    return gmdate('A', $timestamp);
+                    return $dateTime->format('A');
                     break;
 
                 case 'H':
-                    return str_pad(gmdate('G', $timestamp), $length, '0', STR_PAD_LEFT);
+                    return str_pad($dateTime->format('G'), $length, '0', STR_PAD_LEFT);
                     break;
 
                 case 'k':
-                    $hourOfDay = gmdate('G', $timestamp);
+                    $hourOfDay = $dateTime->format('G');
                     $hourOfDay = ('0' == $hourOfDay) ? '24' : $hourOfDay;
                     return str_pad($hourOfDay, $length, '0', STR_PAD_LEFT);
                     break;
 
                 case 'K':
-                    $hourOfDay = gmdate('g', $timestamp);
+                    $hourOfDay = $dateTime->format('g');
                     $hourOfDay = ('12' == $hourOfDay) ? '0' : $hourOfDay;
                     return str_pad($hourOfDay, $length, '0', STR_PAD_LEFT);
                     break;
 
                 case 'm':
-                    $minuteOfHour = (int) gmdate('i', $timestamp);
+                    $minuteOfHour = (int) $dateTime->format('i');
                     return str_pad($minuteOfHour, $length, '0', STR_PAD_LEFT);
                     break;
 
                 case 's':
-                    $secondOfMinute = (int) gmdate('s', $timestamp);
+                    $secondOfMinute = (int) $dateTime->format('s');
                     return str_pad($secondOfMinute, $length, '0', STR_PAD_LEFT);
                     break;
             }

+ 42 - 1
tests/Symfony/Tests/Component/Locale/Stub/StubIntlDateFormatterTest.php

@@ -185,6 +185,31 @@ class StubIntlDateFormatterTest extends \PHPUnit_Framework_TestCase
         );
     }
 
+    public function formatWithTimezoneProvider()
+    {
+        return array(
+            array(0, 'UTC', '1970-01-01 00:00:00'),
+            array(0, 'Europe/Zurich', '1970-01-01 01:00:00'),
+            array(0, 'Europe/Paris', '1970-01-01 01:00:00'),
+            array(0, 'Africa/Cairo', '1970-01-01 02:00:00'),
+            array(0, 'Africa/Casablanca', '1970-01-01 00:00:00'),
+            array(0, 'Africa/Djibouti', '1970-01-01 03:00:00'),
+            array(0, 'Africa/Johannesburg', '1970-01-01 02:00:00'),
+            array(0, 'America/Antigua', '1969-12-31 20:00:00'),
+            array(0, 'America/Toronto', '1969-12-31 19:00:00'),
+            array(0, 'America/Vancouver', '1969-12-31 16:00:00'),
+            array(0, 'Asia/Aqtau', '1970-01-01 05:00:00'),
+            array(0, 'Asia/Bangkok', '1970-01-01 07:00:00'),
+            array(0, 'Asia/Dubai', '1970-01-01 04:00:00'),
+            array(0, 'Australia/Brisbane', '1970-01-01 10:00:00'),
+            array(0, 'Australia/Melbourne', '1970-01-01 10:00:00'),
+            array(0, 'Europe/Berlin', '1970-01-01 01:00:00'),
+            array(0, 'Europe/Dublin', '1970-01-01 01:00:00'),
+            array(0, 'Europe/Warsaw', '1970-01-01 01:00:00'),
+            array(0, 'Pacific/Fiji', '1970-01-01 12:00:00'),
+        );
+    }
+
     /**
     * provides data for cases that are broken in icu/intl
     */
@@ -228,6 +253,22 @@ class StubIntlDateFormatterTest extends \PHPUnit_Framework_TestCase
         }
     }
 
+    /**
+    * @dataProvider formatWithTimezoneProvider
+    */
+    public function testFormatWithTimezone($timestamp, $timezone, $expected)
+    {
+        $pattern = 'yyyy-MM-dd HH:mm:ss';
+
+        $formatter = new StubIntlDateFormatter('en', StubIntlDateFormatter::MEDIUM, StubIntlDateFormatter::SHORT, $timezone, StubIntlDateFormatter::GREGORIAN, $pattern);
+        $this->assertSame($expected, $formatter->format($timestamp), 'Check date format with stub implementation.');
+
+        if (extension_loaded('intl')) {
+            $formatter = new \IntlDateFormatter('en', \IntlDateFormatter::MEDIUM, \IntlDateFormatter::SHORT, $timezone, \IntlDateFormatter::GREGORIAN, $pattern);
+            $this->assertSame($expected, $formatter->format($timestamp), 'Check date format with intl extension.');
+        }
+    }
+
     /**
     * @dataProvider brokenFormatProvider
     */
@@ -249,7 +290,7 @@ class StubIntlDateFormatterTest extends \PHPUnit_Framework_TestCase
      */
     public function testGetCalendar()
     {
-        $formatter = new StubIntlDateFormatter('en', StubIntlDateFormatter::MEDIUM, StubIntlDateFormatter::SHORT);
+        $formatter = new StubIntlDateFormatter('en', StubIntlDateFormatter::MEDIUM, StubIntlDateFormatter::SHORT, 'UTC');
         $formatter->getCalendar();
     }
 }