Skip to content

Commit

Permalink
[BUGFIX] Set timezone on TCA dbType input
Browse files Browse the repository at this point in the history
The value from columns that are marked as "dbType" date(time) fields
in TCA configuration are now explicitly interpreted using UTC timezone,
when the string value has no timezone specifier given.
JS supplied values contain Z as specifier, while records from the database
(which are processed during copy operations) do not contain a timezone
specifier.
Local time was assumed by PHP in the latter case before, as we did not
pass an explicit timezone information to the DateTime constructor.

Therefore we now assure no timezone conversion will happen and no
time/date-offset will be added, by using UTC explicitly.

Resolves: #89914
Releases: master, 10.4, 9.5
Change-Id: I8e531ae5f3367c4493ce1e7db4bec0ef02311e24
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/66670
Tested-by: TYPO3com <noreply@typo3.com>
Tested-by: Markus Klein <markus.klein@typo3.org>
Tested-by: Benjamin Franzke <bfr@qbus.de>
Reviewed-by: Markus Klein <markus.klein@typo3.org>
Reviewed-by: Benjamin Franzke <bfr@qbus.de>
  • Loading branch information
okmiim authored and bnf committed Dec 21, 2020
1 parent e4eee47 commit 89f2e9f
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 2 deletions.
7 changes: 5 additions & 2 deletions typo3/sysext/core/Classes/DataHandling/DataHandler.php
Expand Up @@ -1680,8 +1680,11 @@ protected function checkValueForInput($value, $tcaFieldConf, $table, $id, $realP

// Convert the date/time into a timestamp for the sake of the checks
$emptyValue = $dateTimeFormats[$tcaFieldConf['dbType']]['empty'];
// We store UTC timestamps in the database, which is what getTimestamp() returns.
$dateTime = new \DateTime($value);
// We expect the ISO 8601 $value to contain a UTC timezone specifier.
// We explicitly fallback to UTC if no timezone specifier is given (e.g. for copy operations).
$dateTime = new \DateTime($value, new \DateTimeZone('UTC'));
// The timestamp (UTC) returned by getTimestamp() will be converted to
// a local time string by gmdate() later.
$value = $value === $emptyValue ? null : $dateTime->getTimestamp();
}
}
Expand Down
68 changes: 68 additions & 0 deletions typo3/sysext/core/Tests/Unit/DataHandling/DataHandlerTest.php
Expand Up @@ -365,6 +365,74 @@ public function inputValueCheckDoesNotCallGetDateTimeFormatsForNonDatetimeFields
$this->subject->_call('checkValueForInput', '', $tcaFieldConf, '', 0, 0, '');
}

/**
* @returns array
*/
public function inputValueCheckDbtypeIsIndependentFromTimezoneDataProvider()
{
return [
// Values of this kind are passed in from the inputDateTime control
'time from inputDateTime' => [
'1970-01-01T18:54:00Z',
'time',
'18:54:00',
],
'date from inputDateTime' => [
'2020-11-25T00:00:00Z',
'date',
'2020-11-25',
],
'datetime from inputDateTime' => [
'2020-11-25T18:54:00Z',
'datetime',
'2020-11-25 18:54:00',
],
// Values of this kind are passed in when a data record is copied
'time from copying a record' => [
'18:54:00',
'time',
'18:54:00',
],
'date from copying a record' => [
'2020-11-25',
'date',
'2020-11-25',
],
'datetime from copying a record' => [
'2020-11-25 18:54:00',
'datetime',
'2020-11-25 18:54:00',
],
];
}

/**
* Tests whether native dbtype inputs are parsed independent from the server timezone.
*
* @param $value
* @param $dbtype
* @param $expectedOutput
* @test
* @dataProvider inputValueCheckDbtypeIsIndependentFromTimezoneDataProvider
*/
public function inputValueCheckDbtypeIsIndependentFromTimezone($value, $dbtype, $expectedOutput)
{
$tcaFieldConf = [
'input' => [],
'dbType' => $dbtype,
];

$oldTimezone = date_default_timezone_get();
date_default_timezone_set('Europe/Berlin');

$returnValue = $this->subject->_call('checkValueForInput', $value, $tcaFieldConf, '', 0, 0, '');

// set before the assertion is performed, so it is restored even for failing tests
date_default_timezone_set($oldTimezone);

self::assertEquals($expectedOutput, $returnValue['value']);
}

///////////////////////////////////////////
// Tests concerning checkModifyAccessList
///////////////////////////////////////////
Expand Down

0 comments on commit 89f2e9f

Please sign in to comment.