diff --git a/typo3/sysext/backend/Classes/Form/Element/InputTextElement.php b/typo3/sysext/backend/Classes/Form/Element/InputTextElement.php index 65a16c4c115eaa907415738ca4ab1c3931a714d6..3744941141e0c56d5cdc8adf22a9281f33a4ce3b 100644 --- a/typo3/sysext/backend/Classes/Form/Element/InputTextElement.php +++ b/typo3/sysext/backend/Classes/Form/Element/InputTextElement.php @@ -79,7 +79,7 @@ class InputTextElement extends AbstractFormElement } elseif (in_array('date', $evalList)) { $attributes['data-date-type'] = 'date'; } - if ($parameterArray['itemFormElValue'] > 0) { + if (((int)$parameterArray['itemFormElValue']) !== 0) { $parameterArray['itemFormElValue'] += date('Z', $parameterArray['itemFormElValue']); } if (isset($config['range']['lower'])) { diff --git a/typo3/sysext/backend/Tests/Unit/Form/Element/InputTextElementTest.php b/typo3/sysext/backend/Tests/Unit/Form/Element/InputTextElementTest.php new file mode 100644 index 0000000000000000000000000000000000000000..f144095c19472dbf56335cb0f7530302db95bd75 --- /dev/null +++ b/typo3/sysext/backend/Tests/Unit/Form/Element/InputTextElementTest.php @@ -0,0 +1,109 @@ +<?php +namespace typo3\sysext\backend\Tests\Unit\Form\Element; + +/* + * This file is part of the TYPO3 CMS project. + * + * It is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, either version 2 + * of the License, or any later version. + * + * For the full copyright and license information, please read the + * LICENSE.txt file that was distributed with this source code. + * + * The TYPO3 project - inspiring people to share! + */ + +use TYPO3\CMS\Backend\Form\Element\InputTextElement; +use TYPO3\CMS\Backend\Form\NodeFactory; +use TYPO3\CMS\Core\Tests\UnitTestCase; + +/** + * Test case + */ +class InputTextElementTest extends UnitTestCase +{ + /** + * @var string Selected timezone backup + */ + protected $timezoneBackup = ''; + + /** + * We're fiddling with hard timestamps in the tests, but time methods in + * the system under test do use timezone settings. Therefore we backup the + * current timezone setting, set it to UTC explicitly and reconstitute it + * again in tearDown() + */ + protected function setUp() + { + $this->timezoneBackup = date_default_timezone_get(); + } + + /** + * Tear down + */ + protected function tearDown() + { + date_default_timezone_set($this->timezoneBackup); + parent::tearDown(); + } + + + /** + * Data provider for renderAppliesCorrectTimestampConversion + * + * @return array + */ + public function renderAppliesCorrectTimestampConversionDataProvider() + { + // Three elements: input (UTC), timezone of output, expected output + return [ + // German standard time (without DST) is one hour ahead of UTC + 'date in 2016 in German timezone' => [ + 1457103519, 'Europe/Berlin', 1457103519 + 3600 + ], + 'date in 1969 in German timezone' => [ + -7200, 'Europe/Berlin', -3600 + ], + // Los Angeles is 8 hours behind UTC + 'date in 2016 in Los Angeles timezone' => [ + 1457103519, 'America/Los_Angeles', 1457103519 - 28800 + ], + 'date in UTC' => [ + 1457103519, 'UTC', 1457103519 + ] + ]; + } + + /** + * @test + * @dataProvider renderAppliesCorrectTimestampConversionDataProvider + * @param int $input + * @param string $serverTimezone + * @param int $expectedOutput + */ + public function renderAppliesCorrectTimestampConversion($input, $serverTimezone, $expectedOutput) + { + date_default_timezone_set($serverTimezone); + $data = [ + 'parameterArray' => [ + 'tableName' => 'table_foo', + 'fieldName' => 'field_bar', + 'fieldConf' => [ + 'config' => [ + 'type' => 'input', + 'dbType' => 'datetime', + 'eval' => 'datetime', + 'default' => '0000-00-00 00:00:00' + ] + ], + 'itemFormElValue' => $input + ] + ]; + /** @var NodeFactory $nodeFactoryProphecy */ + $nodeFactoryProphecy = $this->prophesize(NodeFactory::class)->reveal(); + $subject = new InputTextElement($nodeFactoryProphecy, $data); + $result = $subject->render(); + $this->assertContains('<input type="hidden" name="" value="' . $expectedOutput . '" />', $result['html']); + } +} diff --git a/typo3/sysext/core/Classes/DataHandling/DataHandler.php b/typo3/sysext/core/Classes/DataHandling/DataHandler.php index f6f1b0fefd18e5ef86c0cc1a57e8cefc4ac4e482..3ec0c8ad49733c580feecacc8062745736124384 100644 --- a/typo3/sysext/core/Classes/DataHandling/DataHandler.php +++ b/typo3/sysext/core/Classes/DataHandling/DataHandler.php @@ -2663,7 +2663,7 @@ class DataHandler case 'date': case 'datetime': $value = (int)$value; - if ($value > 0 && !$this->dontProcessTransformations) { + if ($value !== 0 && !$this->dontProcessTransformations) { $value -= date('Z', $value); } break; diff --git a/typo3/sysext/core/Tests/Unit/DataHandling/DataHandlerTest.php b/typo3/sysext/core/Tests/Unit/DataHandling/DataHandlerTest.php index 725ad8a8c0a79479c3ead7c1ec6ecdc7585ab4f6..b7ce5ca2483b58fcc5f4c2568ea481a3c4b688ac 100644 --- a/typo3/sysext/core/Tests/Unit/DataHandling/DataHandlerTest.php +++ b/typo3/sysext/core/Tests/Unit/DataHandling/DataHandlerTest.php @@ -167,6 +167,44 @@ class DataHandlerTest extends \TYPO3\CMS\Core\Tests\UnitTestCase } } + public function dataProviderDatetime() + { + // Three elements: input, timezone of input, expected output (UTC) + return [ + // German standard time (without DST) is one hour ahead of UTC + 'date in 2016 in German timezone' => [ + 1457103519, 'Europe/Berlin', 1457103519 - 3600 + ], + 'date in 1969 in German timezone' => [ + -7200, 'Europe/Berlin', -10800 + ], + // Los Angeles is 8 hours behind UTC + 'date in 2016 in Los Angeles timezone' => [ + 1457103519, 'America/Los_Angeles', 1457103519 + 28800 + ], + 'date in UTC' => [ + 1457103519, 'UTC', 1457103519 + ] + ]; + } + + /** + * @test + * @dataProvider dataProviderDatetime + */ + public function evalCheckValueDatetime($input, $serverTimezone, $expectedOutput) + { + $oldTimezone = date_default_timezone_get(); + date_default_timezone_set($serverTimezone); + + $output = $this->subject->checkValue_input_Eval($input, ['datetime'], ''); + + // set before the assertion is performed, so it is restored even for failing tests + date_default_timezone_set($oldTimezone); + + $this->assertEquals($expectedOutput, $output['value']); + } + /** * Data provider for inputValueCheckRecognizesStringValuesAsIntegerValuesCorrectly *