Bladeren bron

[Locale] first implementation of StubIntlDateFormatter

Igor Wiedler 14 jaren geleden
bovenliggende
commit
55ac407458

+ 111 - 0
src/Symfony/Component/Locale/Stub/StubIntlDateFormatter.php

@@ -0,0 +1,111 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien.potencier@symfony-project.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Locale\Stub;
+
+use Symfony\Component\Locale\Locale;
+
+/**
+ * Provides a stub IntlDateFormatter for the 'en' locale.
+ */
+class StubIntlDateFormatter
+{
+    /* formats */
+    const NONE = -1;
+    const FULL = 0;
+    const LONG = 1;
+    const MEDIUM = 2;
+    const SHORT = 3;
+
+    /* formats */
+    const TRADITIONAL = 0;
+    const GREGORIAN = 1;
+
+    public function __construct($locale, $datetype, $timetype, $timezone = null, $calendar = null, $pattern = null)
+    {
+        if ('en' != $locale) {
+            throw new \InvalidArgumentException('Unsupported $locale value. Only the \'en\' locale is supported. Install the intl extension for full localization capabilities.');
+        }
+
+        $this->setPattern($pattern);
+    }
+
+    public function format($timestamp)
+    {
+        $callback = function($matches) use ($timestamp) {
+            $pattern = $matches[0];
+            $length = strlen($pattern);
+
+            switch ($pattern[0]) {
+                case 'M':
+                    $matchLengthMap = array(
+                        1   => 'n',
+                        2   => 'm',
+                        3   => 'M',
+                        4   => 'F',
+                    );
+
+                    if (isset($matchLengthMap[$length])) {
+                       return gmdate($matchLengthMap[$length], $timestamp);
+                    } else if (5 == $length) {
+                        return substr(gmdate('M', $timestamp), 0, 1);
+                    } else {
+                        return str_pad(gmdate('m', $timestamp), $length, '0', STR_PAD_LEFT);
+                    }
+                    break;
+
+                case 'y':
+                    $matchLengthMap = array(
+                        1   => 'Y',
+                        2   => 'y',
+                        3   => 'Y',
+                        4   => 'Y',
+                    );
+
+                    if (isset($matchLengthMap[$length])) {
+                       return gmdate($matchLengthMap[$length], $timestamp);
+                    } else {
+                        return str_pad(gmdate('Y', $timestamp), $length, '0', STR_PAD_LEFT);
+                    }
+                    break;
+
+                case 'd':
+                    return str_pad(gmdate('j', $timestamp), $length, '0', STR_PAD_LEFT);
+                    break;
+            }  
+        };
+
+        $formatted = preg_replace_callback('/(M+|y+|d+)/', $callback, $this->getPattern());
+
+        return $formatted;
+    }
+
+    public function getPattern()
+    {
+        return $this->pattern;
+    }
+
+    public function getCalendar()
+    {
+        $this->throwMethodNotImplementException(__METHOD__);
+    }
+
+    public function setPattern($pattern)
+    {
+        $this->pattern = $pattern;
+    }
+
+    private function throwMethodNotImplementException($methodName)
+    {
+        $message = sprintf('The %s::%s() is not implemented. Install the intl extension for full localization capabilities.', __CLASS__, $methodName);
+        throw new \RuntimeException($message);
+    }
+}

+ 84 - 0
tests/Symfony/Tests/Component/Locale/Stub/StubIntlDateFormatterTest.php

@@ -0,0 +1,84 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien.potencier@symfony-project.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Tests\Component\Locale\Stub;
+
+use Symfony\Component\Locale\Locale;
+use Symfony\Component\Locale\Stub\StubIntlDateFormatter;
+
+class StubIntlDateFormatterTest extends \PHPUnit_Framework_TestCase
+{
+    public function formatProvider()
+    {
+        return array(
+            array('y-M-d', 0, '1970-1-1'),
+
+            /* months */
+            array('M', 0, '1'),
+            array('MM', 0, '01'),
+            array('MMM', 0, 'Jan'),
+            array('MMMM', 0, 'January'),
+            array('MMMMM', 0, 'J'),
+            /* this is stupid */
+            array('MMMMMM', 0, '00001'),
+
+            /* years */
+            array('y', 0, '1970'),
+            array('yy', 0, '70'),
+            array('yyy', 0, '1970'),
+            array('yyyy', 0, '1970'),
+            array('yyyyy', 0, '01970'),
+            array('yyyyyy', 0, '001970'),
+
+            /* day */
+            array('d', 0, '1'),
+            array('dd', 0, '01'),
+            array('ddd', 0, '001'),
+        );
+    }
+
+    /**
+     * @expectedException InvalidArgumentException
+     */
+    public function testConstructorWithUnsupportedLocale()
+    {
+        $formatter = new StubIntlDateFormatter('pt_BR', StubIntlDateFormatter::MEDIUM, StubIntlDateFormatter::SHORT);
+    }
+
+    public function testConstructor()
+    {
+        $formatter = new StubIntlDateFormatter('en', StubIntlDateFormatter::MEDIUM, StubIntlDateFormatter::SHORT, 'UTC', StubIntlDateFormatter::GREGORIAN, 'Y-M-d');
+        $this->assertEquals('Y-M-d', $formatter->getPattern());
+    }
+
+    /**
+    * @dataProvider formatProvider
+    */
+    public function testFormat($pattern, $timestamp, $expected)
+    {
+        $formatter = new StubIntlDateFormatter('en', StubIntlDateFormatter::MEDIUM, StubIntlDateFormatter::SHORT, 'UTC', StubIntlDateFormatter::GREGORIAN, $pattern);
+        $this->assertEquals($expected, $formatter->format($timestamp));
+
+        if (extension_loaded('intl')) {
+            $formatter = new \IntlDateFormatter('en', \IntlDateFormatter::MEDIUM, \IntlDateFormatter::SHORT, 'UTC', \IntlDateFormatter::GREGORIAN, $pattern);
+            $this->assertEquals($expected, $formatter->format($timestamp));
+        }
+    }
+
+    /**
+     * @expectedException RuntimeException
+     */
+    public function testGetCalendar()
+    {
+        $formatter = new StubIntlDateFormatter('en', StubIntlDateFormatter::MEDIUM, StubIntlDateFormatter::SHORT);
+        $formatter->getCalendar();
+    }
+}