PHP: strtotime is returning false for a future date?
Asked Answered
H

5

10

here are some debug expressions i put into eclipse, if you don't believe me:

"strtotime("2110-07-16 10:07:47")" = (boolean) false    
"strtotime("2110-07-16")" = (boolean) false 

i'm using it in my function which returns a random date between the start and end dates:

public static function randomDate($start_date, $end_date, $format = DateTimeHelper::DATE_FORMAT_SQL_DATE)
    {
        if($start_date instanceof DateTime)     $start_date = $start_date->format(DateTimeHelper::DATE_FORMAT_YMDHMS);
        if($end_date instanceof DateTime)       $end_date   = $end_date->format(DateTimeHelper::DATE_FORMAT_YMDHMS);

        // Convert timetamps to millis
        $min = strtotime($start_date);
        $max = strtotime($end_date);

        // Generate random number using above bounds
        $val = rand($min, $max);

        // Convert back to desired date format
        return date($format, $val);
    }

any idea how to get it to return the right unix time for a future date?

thanks!

Henebry answered 16/7, 2010 at 14:49 Comment(4)
We believe you, except it's expected behaviour for the date values you're passing that fall outside of the 32-bit PHP date rangeWundt
From PHP documentation: The valid range of a timestamp is typically from Fri, 13 Dec 1901 20:45:54 UTC to Tue, 19 Jan 2038 03:14:07 UTC. (These are the dates that correspond to the minimum and maximum values for a 32-bit signed integer.) Additionally, not all platforms support negative timestamps, therefore your date range may be limited to no earlier than the Unix epoch. This means that e.g. dates prior to Jan 1, 1970 will not work on Windows, some Linux distributions, and a few other operating systems. PHP 5.1.0 and newer versions overcome this limitation though.Normie
i'm using php 5.3 =S 5.2 on my live server. shouldnt it work, then?Henebry
No, PHP 5.1.0+ fixes the "additionally, not all platforms support negative timestamps" bit, not the "to Tue, 19 Jan 2038" bit.Decoteau
W
12

If you want to work with dates that fall outside the 32-bit integer date range, then use PHP's dateTime objects

try {
    $date = new DateTime('2110-07-16 10:07:47');
} catch (Exception $e) {
    echo $e->getMessage();
    exit(1);
}

echo $date->format('Y-m-d');
Wundt answered 16/7, 2010 at 14:57 Comment(4)
actually, that seems like it is going to kill my randomDate function. how can i make a random date with a DateTime?Henebry
how is this answer accepted when the question was how to get a unix timestamp?Dennard
dateTime objects uk2.php.net/manual/en/book.datetime.php have been available since PHP v5.2.0 and use a 64-bit integer internally, giving a date range from about from about 292 billion years ago to about 292 billion years in the future. This should be adequate for most applications, unless you're a paleobiologist.Wundt
@Dennard because you can call format() with U to get a Unixtime back. See php.net/manual/en/datetime.format.php and php.net/manual/en/function.date.php.Bassarisk
D
12

Try to keep it before Tue, 19 Jan 2038 03:14:07 UTC, when the unix timestamp epoch for 32 bit systems rolls over!

It's even described in the manual at http://php.net/strtotime

edit: Just tested: It's fixed by installing a 64 bit OS and appropriate 64 bit version of php. I guess we have time enough to fix a reincarnated millenium bug:

$one = strtotime("9999-12-31 23:59:59");  
$two = strtotime("10000-01-01 00:00:00");
var_dump($one);
var_dump($two);

int(253402297199)
bool(false)
Dennard answered 16/7, 2010 at 14:50 Comment(3)
Re: Edit - Note that 64-bit PHP (VC9 Thread safe) on Vista 64-bit still uses 32-bit signed integer timestamp range for date valuesWundt
I presume that this is because strtotime() is not a php function, but just a piece of piping to connect to (g)libc (at least in unix land)Dennard
Possibly, I was rather irked when I discovered it while doing some date testing on various platforms recently. It's also interesting to note that the date string formats passed to the dateTime constructor accept a number of formats that strtotime will reject; but I've not looked at the internals to see what the two are usingWundt
W
12

If you want to work with dates that fall outside the 32-bit integer date range, then use PHP's dateTime objects

try {
    $date = new DateTime('2110-07-16 10:07:47');
} catch (Exception $e) {
    echo $e->getMessage();
    exit(1);
}

echo $date->format('Y-m-d');
Wundt answered 16/7, 2010 at 14:57 Comment(4)
actually, that seems like it is going to kill my randomDate function. how can i make a random date with a DateTime?Henebry
how is this answer accepted when the question was how to get a unix timestamp?Dennard
dateTime objects uk2.php.net/manual/en/book.datetime.php have been available since PHP v5.2.0 and use a 64-bit integer internally, giving a date range from about from about 292 billion years ago to about 292 billion years in the future. This should be adequate for most applications, unless you're a paleobiologist.Wundt
@Dennard because you can call format() with U to get a Unixtime back. See php.net/manual/en/datetime.format.php and php.net/manual/en/function.date.php.Bassarisk
N
3

From the PHP manual:

The valid range of a timestamp is typically from Fri, 13 Dec 1901 20:45:54 GMT to Tue, 19 Jan 2038 03:14:07 GMT. (These are the dates that correspond to the minimum and maximum values for a 32-bit signed integer). However, before PHP 5.1.0 this range was limited from 01-01-1970 to 19-01-2038 on some systems (e.g. Windows).

See also: Year 2038 problem - Wikipedia

Nutmeg answered 16/7, 2010 at 14:53 Comment(0)
B
2

You cant convert dates that occur after the unix time rollover (2038)

Brooksbrookshire answered 16/7, 2010 at 14:53 Comment(1)
Gah...Beaten like a ginger stepchild.Brooksbrookshire
F
1

Simple replacement of strtotime

$date = '2199-12-31T08:00:00.000-06:00';

echo date('Y-m-d', strtotime($date)); // fails with 1970 result

echo date_format(  date_create($date) , 'Y-m-d'); // works perfect with 5.2+

Actual post here.

Fluviatile answered 24/4, 2015 at 4:8 Comment(1)
it is not printing the date sirGeehan

© 2022 - 2024 — McMap. All rights reserved.