TCA field with type=input, eval=date with range is broken, always lower range value is applied because of int cast of incoming value before ISO-8601->unix timestamp conversion.
Here an example TCA column from tt_products:
'endtime' => [ 'exclude' => 1, 'label' => 'LLL:EXT:lang/Resources/Private/Language/locallang_general.xlf:LGL.endtime', 'config' => [ 'type' => 'input', 'size' => '8', 'max' => '20', 'eval' => 'date', 'checkbox' => '0', 'default' => '0', 'range' => [ 'upper' => mktime(0, 0, 0, 12, 31, 2020), 'lower' => mktime(0, 0, 0, date('m') - 1, date('d'), date('Y')) ] ] ],
This is correct according to the documentation: https://docs.typo3.org/typo3cms/TCAReference/ColumnsConfig/Type/Input.html#range
However, the core handles ranges (as integer) before it converts the date. Therefore, ranges are now broken for eval=date input columns.
This is caused by: https://docs.typo3.org/typo3cms/extensions/core/Changelog/8.5/Important-77702-CustomRenderTypesForDateAndDatetimeFieldsMustUseISO-8601.html?highlight=date
which also caused the distantly related bug https://forge.typo3.org/issues/82981
What happens is the following:
\TYPO3\CMS\Core\DataHandling\DataHandler::checkValueForInput() checks for the TCA range and compares the
$tcaFieldConf['range']['lower'] / ['upper'] both cast to "(int)".
As the incoming date is in ISO-8601, it will look like
"2018-01-01T00:00:00+00:00". Casting it to integer to compare with the upper/lower range, the value becomes simply "2018". At this point, the lower end of the range (
$tcaFieldConf['range']['lower']) is applied to
\TYPO3\CMS\Core\DataHandling\DataHandler::checkValue_input_Eval() is called, which then attempts to convert the ISO-8601 string to a unix timestamp - but at this point we already lost our original incoming ISO-8601 string, since the lower range value was already applied.