PHP strtotime Limitation

September 20, 2005

I have been relying very heavily on strtotime() in PHP in just about everything I write. For those not entirely familiar with this function, strtotime() will "parse about any English textual datetime description into a Unix timestamp." The ones I get most excited about are the MySQL date format: 2005-10-21 or the more common us representation of 3/22/05. Another great use is to put stuff in like "-3 days" or "yesterday".

Why create Unix timestamps you may wonder? Well, there are all kinds of things that happily take timestamps and do fun things with them. My favorite example is the date() function. The first parameter to date is the format you want results in, the second is optionally a Unix timestamp. A call to date like date('m/d/Y'); will generate a reasonably nice US representation of today's date. However, if you did date('m/d/Y',strtotime('3 weeks ago')); you can get the nice readable format provided by date, but for some arbitrary date you are deciding upon with strtotime. Also, knowing strtotime happily accepts the MySQL date format, when you get data back from a table and want to display it to the end user nicely, the same chaining example I just did works again: date('m/d/Y',strtotime($row['date_field']));. For a complete list of the available date formats, visit PHP.net.

Ok, so the title of this makes reference to a limitation... on to that. On some operating systems when running PHP versions < 5.1, a date like 1956-07-11 makes strtotime return -1, which is an error. Unix timestamps start at the epoch, which is January 1, 1970 (1970-01-01). A '-1' passed along to the date function will get you back December 31, 1969 (at 23:59:59) because you are saying 1 second before midnight of the Unix Epoch. (Note: you may also see the date of 1969-12-31 in a case where you have an empty MySQL date of 0000-00-00, which is very common). This is hugely frustrating, but thankfully is resolved in 5.1.

In the meantime, Ed Lecky-Thompson wrote a very useful safestrtotime() function and shared it on PHP.net. I'm reproducing it here for my convenience, altered to match the code formatting I prefer.

PHP:
  1. <?php
  2.  
  3. function safestrtotime($strInput)
  4. {
  5.     $iVal = -1;
  6.     for ($i=1900; $i<=1969; $i++)
  7.     {
  8.         // Check for this year string in date
  9.         $strYear = (string)$i;
  10.         if (!(strpos($strInput, $strYear)===false))
  11.         {
  12.             $replYear = $strYear;
  13.             $yearSkew = 1970 - $i;
  14.             $strInput = str_replace($strYear, '1970', $strInput);
  15.         }
  16.     }
  17.     $iVal = strtotime($strInput);
  18.     if ($yearSkew> 0)
  19.     {
  20.         $numSecs = (60 * 60 * 24 * 365 * $yearSkew);
  21.         $iVal = $iVal - $numSecs;
  22.         $numLeapYears = 0// determine number of leap years in period
  23.         for ($j=$replYear; $j<=1969; $j++)
  24.         {
  25.             $thisYear = $j;
  26.             $isLeapYear = false;
  27.             // Is div by 4?
  28.             if (($thisYear % 4) == 0)
  29.             {
  30.                 $isLeapYear = true;
  31.             }
  32.             // Is div by 100?
  33.             if (($thisYear % 100) == 0)
  34.             {
  35.                 $isLeapYear = false;
  36.             }
  37.             // Is div by 1000?
  38.             if (($thisYear % 1000) == 0)
  39.             {
  40.                 $isLeapYear = true;
  41.             }
  42.             if ($isLeapYear == true)
  43.             {
  44.                 $numLeapYears++;
  45.             }
  46.         }
  47.         $iVal = $iVal - (60 * 60 * 24 * $numLeapYears);
  48.     }
  49.     return $iVal;
  50. }
  51. ?>

1970-01-01, date format, datetime, ed lecky-thompson, epoch, function, mysql, operating systems, php.net, timestamp, timestamps, unix epoch, unix timestamp

Tags: , , , , , , , , , , , ,

Related:


Comments

5 Responses to “PHP strtotime Limitation”

  1. NoSheep! » Disclaimer for Plymouth State Readers and Concerned Citizens on October 12th, 2005 11:59 am

    [...] Additionally, content has been categorized. Certain categories may contain more professional topics than others (for instance PHP, Identity Management, and Technology in general). Other categories such as Humor, Entertainment, Vacation and Travel, and General News are more likely to contain offensive or adult material. [...]

  2. Dwight on April 13th, 2006 5:37 am

    wow! this function was super helpful. thanks so much.

  3. amir on March 28th, 2007 7:25 am

    it gives error like this
    Undefined variable: yearSkew in c:\inetpub\wwwroot\qcadmin\Untitled-1.php on line 18

  4. zbtirrell on March 28th, 2007 5:29 pm

    That’s a PHP strict error, I have not initialized all variables in this script to be strict mode compatible…

  5. German on December 19th, 2007 11:28 am

    When used in PHP on Windows, it displays:

    Warning: date(): Windows does not support dates prior to midnight (00:00:00), January 1, 1970

Got something to say?





User contributed tags: php strtotime (927) - t (702) - strtotime (306) - strtotime PHP (302) - php strtotime mysql (106) - strtotime examples (96) - strtotime mysql (77) - strtotime 1970 (76) - safestrtotime (72) - PHP mysql strtotime (67) - strtotime in php (67) - php strtotime format (61) - Limitation of PHP (56) - "strtotime example" (56) - php strtotime 1970 (54) - php date before 1970 (49) - strtotime before 1970 (47) - strtotime yesterday (45) - strtotime format (45) - +php +date +1969 (41) - php strtotime function (39) - f (36) - strtotime 1969 (36) - strtotime mysql timestamp (35) - php isleapyear (35) - adodb strtotime (34) - mysql strtotime (34) - php strtotime 1969 (31) - php timestamp yesterday (27) - isLeapYear php (26) - php strtotime example (25) - strtotime function in php (25) - strtotime("Yesterday") (24) - php strtotime yesterday (24) - php strtotime examples (24) - php timestamp before 1970 (24) - strtotime mysql date (23) - mysql epoch (22) - php date before 1900 (20) - mysql php strtotime (20) - MYSQL timestamp yesterday (20) - unix timestamp limitation (18) - strtotime+php (18) - php date strtotime (17) - php strtotime before 1970 (16) - php date 1900 (16) - php + date to epoch (15) - mysql date strtotime (15) - php safestrtotime (15) - strtotime mysql php (15) - php strtotime formats (15) - php date limitation (15) - strtotime formats (15) - strtotime error (14) - Unix timestamp limitations (14) - php strtotime midnight (14) - php dates before 1970 (14) - strtotime mysql datetime (14) - date strtotime (13) - man strtotime (13) - strtotime midnight (13) - strtotime php mysql (13) - php strtotime mysql timestamp (12) - php dates before 1900 (12) - php,strtotime (12) - all (12) - php timestamp midnight (12) - php date limitations (11) - php timestamp 1970 (11) - epoch php (10) - php limitation (10) - php dates before 1969 (10) - php strtotime 1900 (10) - php date midnight (10) - strtotime( php 4 (9) - PHP strtotime error (9) - mysql date yesterday (9) - strtotime adodb (9) - php strtotime mysql datetime (9) - php date before epoch (9) - strtotime php 1970 (9) - php timestamp 1969 (9) - php string limitation (9) - php strtotime "0000-00-00" (9) - mysql date before 1970 (8) - strtotime 1900 (8) - php timestamp limitation (8) - php strtotime mysql date (8) - php function strtotime (8) - php date format 1969 (7) - php format strtotime (7) - php date epoch (7) - date function (7) - PHP dates before epoch (7) - php '1969-12-31' (7) - php format epoch (7) - php yesterday strtotime (7) - php format date before 1970 (7) - php epoch (7) - php mysql 1969 (6) - strtotime "0000-00-00" (6) - timestamp limitation (6) - php date 1970 (6) - mysql date 1969 (6) - PHP strtotime date format (6) - mysql 1969 (6) - php date function yesterday (6) - unix timestamp 1969 (6) - unix timestamp yesterday (6) - php yesterday timestamp (6) - php mysql date 1969 (6) - mysql timestamp php strtotime (6) - php timestamp before epoch (6) - php date before-1969 (6) - timestamp to epoch +php (6) - php strtotime limitations (6) - 1969-12-31 php date (5) - php strtotime("yesterday") (5) - php date function 1969 (5) - php timestamp limitations (5) - strtotime epoch (5) - strtotime yesterday +php (5) - strtotime before 1969 (5) - strtotime 1970-01-01 (5) - php date 1969-12-31 (5) - php strict strtotime (5) - strtotime mysql format (5) - strtotime php format (5) - strtotime limitations (5) - php strtotime "-1" (5) - php strtotime 1969-12-31 (5) - php strtotime february (5) - php date format strtotime (5) - php strtotime datetime (5) - php strtotime timestamp (5) - php mysql date strtotime (5) - php strtotime limitation (5) - Edward Lecky-Thompson (5) - mysql datetime strtotime (5) - strtotime tutorial (5) - strtotime date (5) - strtotime + php function (5) - php strtotime tutorial (5) - strtotime 0000-00-00 php (5) - timestamp before 1970 (5) - php mysql date to epoch (5) - mysql date limitations (4) - php strtotime windows (4) - strtotime returns 1970 (4) - date before 1970 php (4) -