From b5006c26ffd5f1badaf4d58ea6c849e7907e5b4e Mon Sep 17 00:00:00 2001 From: Anja Leichsenring Date: Sun, 3 Feb 2013 14:11:44 +0100 Subject: [PATCH] [BUGFIX] Date ViewHelper not using configured Timezones 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 --- .../ViewHelpers/Format/DateViewHelper.php | 24 +++- .../ViewHelpers/Format/DateViewHelperTest.php | 105 ++++++++++++++++++ 2 files changed, 127 insertions(+), 2 deletions(-) diff --git a/typo3/sysext/fluid/Classes/ViewHelpers/Format/DateViewHelper.php b/typo3/sysext/fluid/Classes/ViewHelpers/Format/DateViewHelper.php index eed554ea4922..7fa1d79e3d63 100644 --- a/typo3/sysext/fluid/Classes/ViewHelpers/Format/DateViewHelper.php +++ b/typo3/sysext/fluid/Classes/ViewHelpers/Format/DateViewHelper.php @@ -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) * * + * + * {dateObject} + * + * + * 13. Dezember 1980 + * (depending on the current date and defined locale. In the example you see the 1980-12-13 in a german locale) + * + * * * {f:format.date(date: dateObject)} * @@ -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); + } + } } diff --git a/typo3/sysext/fluid/Tests/Unit/ViewHelpers/Format/DateViewHelperTest.php b/typo3/sysext/fluid/Tests/Unit/ViewHelpers/Format/DateViewHelperTest.php index aadb272b12ab..b88d1fc9c60c 100644 --- a/typo3/sysext/fluid/Tests/Unit/ViewHelpers/Format/DateViewHelperTest.php +++ b/typo3/sysext/fluid/Tests/Unit/ViewHelpers/Format/DateViewHelperTest.php @@ -12,6 +12,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 */ @@ -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 -- 2.20.1