Bug #83916
closedViewHelper f:format.date can't handle unix timestamp > 2147483648
0%
Description
This Fluid
<f:format.date>2247483648</f:format.date>
results in
#1241722579: "2247483648" could not be parsed by \DateTime constructor: DateTime::__construct(): Failed to parse time string (@) at position 0 (@): Unexpected character (More information)
Problem is function MathUtility::canBeInterpretedAsInteger in DateViewHelper, which checks the unix timestamp for integer. But unix timestamp is no integer, it can be much larger than an integer.
Updated by Mathias Schreiber almost 7 years ago
- Status changed from New to Accepted
- Assignee set to Mathias Schreiber
please run this code on your machine:
<?php
function testInteger()
{
return is_int(2247483648);
}
function buildDate()
{
return new \DateTime('@' . 2247483648);
}
var_dump(testInteger());
var_dump(buildDate());
The result on my machine is:
/Volumes/Web/docRoot/typo3-core/Web/fileadmin/test.php:13:boolean true
/Volumes/Web/docRoot/typo3-core/Web/fileadmin/test.php:14:
object(DateTime)[1]
public 'date' => string '2041-03-21 13:00:48.000000' (length=26)
public 'timezone_type' => int 1
public 'timezone' => string '+00:00' (length=6)
Updated by Mathias Schreiber almost 7 years ago
I just added two 0 to the timestamp.
/Volumes/Web/docRoot/typo3-core/Web/fileadmin/test.php:13:boolean true
/Volumes/Web/docRoot/typo3-core/Web/fileadmin/test.php:14:
object(DateTime)[1]
public 'date' => string '9091-12-29 05:20:00.000000' (length=26)
public 'timezone_type' => int 1
public 'timezone' => string '+00:00' (length=6)
Are you running a 32bit system?!?
Updated by Mathias Schreiber almost 7 years ago
- Status changed from Accepted to Needs Feedback
Updated by Mathias Schreiber almost 7 years ago
- Status changed from Needs Feedback to Closed
Updated by Sven Burkert almost 7 years ago
I get
bool(false) object(DateTime)#1 (3) { ["date"]=> string(26) "2041-03-21 13:00:48.000000" ["timezone_type"]=> int(1) ["timezone"]=> string(6) "+00:00" }
So is_int fails. I'm running a 64-bit system, but MAMP runs in 32-bit. But I'm getting the same results on a managed server from DomainFactory (nearly all DomainFactory servers run with 32-bit and I think from many other hosters, too).
But shouldn't TYPO3 also run on 32-bit systems? I can't find requirements for 64-bit (https://github.com/TYPO3/TYPO3.CMS/blob/TYPO3_8-7/INSTALL.md).
Updated by Mathias Schreiber almost 7 years ago
The scenarios I thought of:
- remove is_int doesn't work because the VH accepts both strings and integer values and decides based on the input value
- use is_numeric doesn't work because floats are numeric, too
- introduce a new VH for UnixTimestamps and remove the old functionality would be a breaking change
Updated by Stephan Großberndt almost 7 years ago
- Status changed from Closed to Needs Feedback
- Start date deleted (
2018-02-15) - Complexity deleted (
easy)
Hm, on 32-bit systems (32-bit PHP on 64-bit OS makes this 32-bit) you are bound to the int restrictions of 32-bit. With 32-bit you can't handle dates >year 2038 being represented by ints. So fluid would be able to cope with it but if you want to save those values in the database (assuming mysql running with 32-bit too) it will break again.
Another option I see is to adjust DateViewHelper:
$base = $base instanceof \DateTimeInterface ? $base->format('U') : strtotime((MathUtility::canBeInterpretedAsInteger($base) ? '@' : '') . $base); $dateTimestamp = strtotime((MathUtility::canBeInterpretedAsInteger($date) ? '@' : '') . $date, $base);
Do not use MathUtility::canBeInterpretedAsInteger()
(as apparently the number can be bigger as representable by int
) but some other kind of check e.g. preg_match
(slow) or is_numeric
.
After some research I guess is_numeric
is the way to go: According to http://php.net/manual/de/function.is-numeric.php#102011 is_numeric
can handle very big numbers.
Could you please test this:
<?php function testNumeric() { return is_numeric(2247483648); } function buildDate() { return new \DateTime('@' . 2247483648); } var_dump(testNumeric()); var_dump(buildDate());
If that works
$base = $base instanceof \DateTimeInterface ? $base->format('U') : strtotime((is_numeric($base) ? '@' : '') . $base); $dateTimestamp = strtotime((is_numeric($date) ? '@' : '') . $date, $base);
would be an appropriate patch
Updated by Kevin Ditscheid almost 7 years ago
I have a splitted opinion about this one, because as soon as \DateTime::getTimestamp() will come in, all will break apart again. A real solution can only be the hoster updating its systems to a 64bit variant.
Updated by Georg Ringer over 6 years ago
so what about a report which sets a warning if 32bit is used?
Updated by Claus Due over 6 years ago
- Category changed from Fluid to Reports
I suggest either closing this issue or turning it into a TASK to add a new report that warns about 32 bit systems, as suggested by Georg. I've taken the liberty of removing the Fluid category as this doesn't only pertain to Fluid - and assigning it to the Reports category.
Alternatively this may better belong in "core" if we need to somehow declare 64bit as hard requirement.
Updated by Benni Mack over 4 years ago
- Status changed from Needs Feedback to Closed
Hey all,
as this is a 32 bit issue (and apparantly most hosters with 32bit systems are currently migrating away to 64bit - same goes for Mac OS etc), this issue will be "fixed" on its own. I'm glad to have it this way, otherwise this would have meant that we would have to refactor most of TYPO3's Core APIs. This way, we're safe - if somebody needs these kind of things, one should upgrade to a 64 bit system.