[BUGFIX] Date ViewHelper not using configured Timezones
authorAnja Leichsenring <aleichsenring@ab-softlab.de>
Sun, 3 Feb 2013 13:11:44 +0000 (14:11 +0100)
committerAnja Leichsenring <aleichsenring@ab-softlab.de>
Wed, 6 Feb 2013 20:25:10 +0000 (21:25 +0100)
The date viewhelper does not respect the configured timezone.

After the default timezone is set during Bootstrap, it is enough to
retrieve the setting from environment.

Additional a condition tests the proper format of timestamps and adds
the '@' if it is missing.

For the formatted output with '%' strftime function is added, too.

Fixes: #12769, #43363, #9174
Releases: 4.5, 4.6, 4.7, 6.0, 6.1
Change-Id: I782b4ec00537519768335da9ba32822a42108ea1
Reviewed-on: https://review.typo3.org/17976
Reviewed-by: Wouter Wolters
Tested-by: Wouter Wolters
Reviewed-by: Jigal van Hemert
Tested-by: Jigal van Hemert
Reviewed-by: Anja Leichsenring
Tested-by: Anja Leichsenring
typo3/sysext/fluid/Classes/ViewHelpers/Format/DateViewHelper.php
typo3/sysext/fluid/Tests/Unit/ViewHelpers/Format/DateViewHelperTest.php

index eed554e..7fa1d79 100644 (file)
@@ -47,6 +47,14 @@ namespace TYPO3\CMS\Fluid\ViewHelpers\Format;
  * (depending on the current time. Don't forget the "@" in front of the timestamp see http://www.php.net/manual/en/function.strtotime.php)
  * </output>
  *
+ * <code title="Localized dates using strftime date format">
+ * <f:format.date format="%d. %B %Y">{dateObject}</f:format.date>
+ * </code>
+ * <output>
+ * 13. Dezember 1980
+ * (depending on the current date and defined locale. In the example you see the 1980-12-13 in a german locale)
+ * </output>
+ *
  * <code title="Inline notation">
  * {f:format.date(date: dateObject)}
  * </code>
@@ -65,6 +73,7 @@ namespace TYPO3\CMS\Fluid\ViewHelpers\Format;
  *
  * @api
  */
+
 class DateViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper {
 
        /**
@@ -90,12 +99,23 @@ class DateViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper
                }
                if (!$date instanceof \DateTime) {
                        try {
-                               $date = new \DateTime($date);
+                               if (is_integer($date)) {
+                                       $date = new \DateTime('@' . $date);
+                               } else {
+                                       $date = new \DateTime($date);
+                               }
+                               $date->setTimezone(new \DateTimeZone(date_default_timezone_get()));
                        } catch (\Exception $exception) {
                                throw new \TYPO3\CMS\Fluid\Core\ViewHelper\Exception('"' . $date . '" could not be parsed by DateTime constructor.', 1241722579);
                        }
                }
-               return $date->format($format);
+
+               if (strpos($format, '%') !== FALSE) {
+                       return strftime($format, $date->format('U'));
+               } else {
+                       return $date->format($format);
+               }
+
        }
 }
 
index aadb272..b88d1fc 100644 (file)
@@ -13,6 +13,35 @@ namespace TYPO3\CMS\Fluid\Tests\Unit\ViewHelpers\Format;
 class DateViewHelperTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
 
        /**
+        * @var array Backup of current locale, it is manipulated in tests
+        */
+       protected $backupLocales = array();
+
+       /**
+        * @var string Backup of current timezone, it is manipulated in tests
+        */
+       protected $timezone;
+
+       public function setUp() {
+               parent::setUp();
+               // Store all locale categories manipulated in tests for reconstruction in tearDown
+               $this->backupLocales = array(
+                       'LC_COLLATE' => setlocale(LC_COLLATE, 0),
+                       'LC_CTYPE' => setlocale(LC_CTYPE, 0),
+                       'LC_MONETARY' => setlocale(LC_MONETARY, 0),
+                       'LC_TIME' => setlocale(LC_TIME, 0),
+               );
+               $this->timezone = @date_default_timezone_get();
+       }
+
+       public function tearDown() {
+               foreach ($this->backupLocales as $category => $locale) {
+                       setlocale(constant($category), $locale);
+               }
+               date_default_timezone_set($this->timezone);
+       }
+
+       /**
         * @test
         */
        public function viewHelperFormatsDateCorrectly() {
@@ -77,6 +106,82 @@ class DateViewHelperTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
                $actualResult = $viewHelper->render('1980-12-12');
                $this->assertEquals('1980-12-12', $actualResult);
        }
+
+       /**
+        * @test
+        */
+       public function viewHelperRespectsDefaultTimezoneForIntegerTimestamp() {
+               $viewHelper = $this->getMock('TYPO3\\CMS\\Fluid\\ViewHelpers\\Format\\DateViewHelper', array('renderChildren'));
+
+               $date = 1359891658; // 2013-02-03 11:40 UTC
+               $format = 'Y-m-d H:i';
+
+               date_default_timezone_set('Europa/Berlin');
+               $expected = '2013-02-03 12:40';
+               $this->assertEquals($expected, $viewHelper->render($date, $format));
+
+               date_default_timezone_set('Asia/Riyadh');
+               $expected = '2013-02-03 14:40';
+               $this->assertEquals($expected, $viewHelper->render($date, $format));
+       }
+
+       /**
+        * @test
+        */
+       public function viewHelperRespectsDefaultTimezoneForStringTimestamp() {
+               $viewHelper = $this->getMock('TYPO3\\CMS\\Fluid\\ViewHelpers\\Format\\DateViewHelper', array('renderChildren'));
+
+               $format = 'Y-m-d H:i';
+
+               date_default_timezone_set('Europa/Berlin');
+               $date = '@1359891658'; // 2013-02-03 11:40 UTC
+               $expected = '2013-02-03 12:40';
+               $this->assertEquals($expected, $viewHelper->render($date, $format));
+
+               $date = '03/Oct/2000:14:55:36 +0400'; // Moscow
+               $expected = '2000-10-03 12:55';
+               $this->assertEquals($expected, $viewHelper->render($date, $format));
+
+               date_default_timezone_set('Asia/Riyadh');
+               $date = '@1359891658'; // 2013-02-03 11:40 UTC
+               $expected = '2013-02-03 14:40';
+               $this->assertEquals($expected, $viewHelper->render($date, $format));
+
+               $date = '03/Oct/2000:14:55:36 +0400'; // Moscow
+               $expected = '2000-10-03 13:55';
+               $this->assertEquals($expected, $viewHelper->render($date, $format));
+       }
+
+       /**
+        * @test
+        */
+       public function dateViewHelperFormatsDateLocalized() {
+               $viewHelper = $this->getMock('TYPO3\\CMS\\Fluid\\ViewHelpers\\Format\\DateViewHelper', array('renderChildren'));
+               $format = '%d. %B %Y';
+               $timestamp = '@1359891658'; // 2013-02-03 11:40 UTC
+
+               $locale = 'de_DE.UTF-8';
+               if (!setlocale(LC_COLLATE, $locale)) {
+                       $this->markTestSkipped('Locale ' . $locale . ' is not available.');
+               }
+               $this->setLocale($locale);
+               $expected = '03. Februar 2013';
+               $this->assertEquals($expected, $viewHelper->render($timestamp, $format));
+
+               $locale = 'en_ZW.utf8';
+               if (!setlocale(LC_COLLATE, $locale)) {
+                       $this->markTestSkipped('Locale ' . $locale . ' is not available.');
+               }
+               $this->setLocale($locale);
+               $expected = '03. February 2013';
+               $this->assertEquals($expected, $viewHelper->render($timestamp, $format));
+       }
+
+       protected function setLocale($locale) {
+               setlocale(LC_CTYPE, $locale);
+               setlocale(LC_MONETARY, $locale);
+               setlocale(LC_TIME, $locale);
+       }
 }
 
 ?>
\ No newline at end of file