You are not restricted to the same date ranges when running PHP on a 64-bit machine. This is because you are using 64-bit integers instead of 32-bit integers (at least if your OS is smart enough to use 64-bit integers in a 64-bit OS)
The following code will produce difference output in 32 and 64 bit environments.
var_dump(strtotime('1000-01-30'));
32-bit PHP: bool(false)
64-bit PHP: int(-30607689600)
This is true for php 5.2.* and 5.3
Also, note that the anything about the year 10000 is not supported. It appears to use only the last digit in the year field. As such, the year 10000 is interpretted as the year 2000; 10086 as 2006, 13867 as 2007, etc
strtotime
(PHP 4, PHP 5)
strtotime — Parse about any English textual datetime description into a Unix timestamp
Description
The function expects to be given a string containing a US English date format and will try to parse that format into a Unix timestamp (the number of seconds since January 1 1970 00:00:00 UTC), relative to the timestamp given in now , or the current time if now is not supplied.
This function will use the TZ environment variable (if available) to calculate the timestamp. Since PHP 5.1.0 there are easier ways to define the timezone that is used across all date/time functions. That process is explained in the date_default_timezone_get() function page.
Note: If the number of the year is specified in a two digit format, the values between 00-69 are mapped to 2000-2069 and 70-99 to 1970-1999. See the notes below for possible differences on 32bit systems (possible dates might end on 2038-01-19 03:14:07).
Parameters
- time
-
The string to parse. Before PHP 5.0.0, microseconds weren't allowed in the time, since PHP 5.0.0 they are allowed but ignored.
- now
-
The timestamp which is used as a base for the calculation of relative dates.
Return Values
Returns a timestamp on success, FALSE otherwise. Previous to PHP 5.1.0, this function would return -1 on failure.
Errors/Exceptions
Every call to a date/time function will generate a E_NOTICE if the time zone is not valid, and/or a E_STRICT or E_WARNING message if using the system settings or the TZ environment variable. See also date_default_timezone_set()
Changelog
| Version | Description |
|---|---|
| 5.1.0 | It now returns FALSE on failure, instead of -1. |
| 5.1.0 | Now issues the E_STRICT and E_NOTICE time zone errors. |
Examples
Example #1 A strtotime() example
<?php
echo strtotime("now"), "\n";
echo strtotime("10 September 2000"), "\n";
echo strtotime("+1 day"), "\n";
echo strtotime("+1 week"), "\n";
echo strtotime("+1 week 2 days 4 hours 2 seconds"), "\n";
echo strtotime("next Thursday"), "\n";
echo strtotime("last Monday"), "\n";
?>
Example #2 Checking for failure
<?php
$str = 'Not Good';
// previous to PHP 5.1.0 you would compare with -1, instead of false
if (($timestamp = strtotime($str)) === false) {
echo "The string ($str) is bogus";
} else {
echo "$str == " . date('l dS \o\f F Y h:i:s A', $timestamp);
}
?>
Notes
In PHP 5 up to 5.0.2, "now" and other relative times are wrongly computed from today's midnight. It differs from other versions where it is correctly computed from current time.
In PHP versions prior to 4.4.0, "next" is incorrectly computed as +2. A typical solution to this is to use "+1".
Note: 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.
strtotime
25-Jun-2009 11:13
02-Jun-2009 08:52
I've noticed that 'first monday' and '1 monday' are not treated equally.
To get the 1st of june 2009 when searching for the first monday:
Use 'first monday' and start from june 0:
$time= strtotime("first monday ", mktime(0, 0, 0, 06, 0, 2009));
echo "first monday " . date("d-m-Y", $time) . "<br />";
Or use '1 monday' and start from june 1:
$time= strtotime("1 monday ", mktime(0, 0, 0, 06, 1, 2009));
echo "1 monday " . date("d-m-Y", $time) . "<br />";
Took me a long time to figure this out.
28-May-2009 10:42
Observed date formats that strtotime expects, it can be quite confusing, so hopefully this makes things a little clearer for some.
mm/dd/yyyy - 02/01/2003 - strtotime() returns : 1st February 2003
mm/dd/yy - 02/01/03 - strtotime() returns : 1st February 2003
yyyy/mm/dd - 2003/02/01 - strtotime() returns : 1st February 2003
dd-mm-yyyy - 01-02-2003 - strtotime() returns : 1st February 2003
yy-mm-dd - 03-02-01 - strtotime() returns : 1st February 2003
yyyy-mm-dd - 2003-02-01 - strtotime() returns : 1st February 2003
14-May-2009 01:08
A warning for those that think that their is only one way to interpret 2009 April 4th...PHP thinks otherwise.
<?php
$test = "April 4th 2009";
if (strtotime($test) === false) {
echo "test == false <br />\n t = $test";
}
else {
echo "test == true";
}
?>
Works fine, with the American 'Month Day Year'.
<?php
$test = "2009 April 4th";
if (strtotime($test) === false) {
echo "test == false <br />\n t = $test";
}
else {
echo "test == true";
}
?>
Will produce a false result. It seems that even with a 4 figure year that the American date format overrules the obviousness of 2009 April 4th.
02-Apr-2009 08:29
Fails for non-US dates where the ordering is uncertain, such as 01/02/2003 - parses this as Feb 1st, rather than Jan 2nd.
If you are parsing dates for a non-US locale, you can flip these elements of your date:
<?php
$y = $_POST['date'];
if (preg_match('/^\s*(\d\d?)[^\w](\d\d?)[^\w](\d{1,4}\s*$)/', $y, $match)) {
$y = $match[2] . '/' . $match[1] . '/' . $match[3];
}
echo date('d # m # Y', strtotime($y));
?>
WARNING: Above only works for dates, and breaks for times: 12:30:01 will be converted to 30/12/01.
This absolutely ought to be a flag to strtotime(), either as a boolean "monthfirst" flag, or a boolean "respect my locale" flag. Since it isn't, kludge is needed.
30-Mar-2009 01:57
If you look for function to convert date from RSS pubDate, always make sure to check correct input format, found that for date("r") or "D, d M o G:i:s T" strtotime may return wrong result.
21-Mar-2009 03:18
Here's a hack to make this work for MS SQL's datetime junk, since strtotime() has issues with fractional seconds.
<?php
$MSSQLdatetime = "Feb 7 2009 09:48:06:697PM";
$newDatetime = preg_replace('/:[0-9][0-9][0-9]/','',$MSSQLdatetime);
$time = strtotime($newDatetime);
echo $time."\n";
?>
12-Mar-2009 01:41
Another way to get the last day of a given month is to use date('t');
27-Feb-2009 05:40
Just an FYI, the Pear Date package addresses many of the topics covered in the notes below (finding last day of month, start date of next week, etc.)
25-Feb-2009 06:43
After looking around I couldn't find any code that would properly and simply compute the last day of the month. +1 month will not work ex. 1 month after February 28th is March 3rd.
This line of code returns the last day of the current month:
<?php
echo 'Last day of the month: ' . date('m/d/y h:i a',(strtotime('next month',strtotime(date('m/01/y'))) - 1));
?>
It uses the first of the current month, gets the first of the next month, then subtracts 1 second to give you 11:59pm on the last day of the current month.
Hope this helps someone.
11-Feb-2009 04:40
Here's a revised version of [code I originally wrote on 21-JAN-09]. You can work out the number of days left in the month or year like this. [This version] also works with arbitrary dates given to it rather than only working with the current date:
<?php
function days_left_in_month($isoDate) {
$date = explode('-', $isoDate);
$date[1]++;
$date[1] = str_pad($date[1], 2, '0', STR_PAD_LEFT);
if ($date[1] == '13') {
$date[0]++;
$date[1] = '01';
}
$date[2] = '01';
$isoDateNextMonth = implode('-', $date);
return ceil((strtotime($isoDateNextMonth) - strtotime($isoDate)) / 86400);
}
echo days_left_in_month('2009-01-31'); // Much better
?>
[EDIT BY danbrown AT php DOT net: Contains bugfixes by (akniep AT rayo DOT info) on 03-FEB-09 and the original author.]
03-Feb-2009 04:37
The "+1 month" issue solved as in MySQL.
========================================
As noted in several comments, PHP's strtotime() solves the "+1 month" ("next month") issue on days that do not exist in the subsequent month differently than other implementations like for example MySQL.
// PHP: 2009-03-03
<?php
echo date( "Y-m-d", strtotime( "2009-01-31 +1 month" ) );
?>
// MySQL: 2009-02-28
<?php
SELECT DATE_ADD( '2009-01-31', INTERVAL 1 MONTH );
?>
========================================
If not for consistency with MySQL there are several reasons why one may need a PHP-function that calculates "+1 month" as MySQL does. Certainly, for various kinds of business logic it seems much more intuitiv to land on a date within the subsequent month rather than on a date within the next but one if you calculate "next month" ("+1 month").
The following function calculates a date X months in the future of a given date ($base_time).
<?php
/**
* Calculates a date lying a given number of months in the future of a given date.
* The results resemble the logic used in MySQL where '2009-01-31 +1 month' is '2009-02-28' rather than '2009-03-03' (like in PHP's strtotime).
*
* @author akniep
* @since 2009-02-03
* @param $base_time long, The timestamp used to calculate the returned value .
* @param $months int, The number of months to jump to the future of the given $base_time.
* @return long, The timestamp of the day $months months in the future of $base_time
*/
function get_x_months_to_the_future( $base_time = null, $months = 1 )
{
if (is_null($base_time))
$base_time = time();
$x_months_to_the_future = strtotime( "+" . $months . " months", $base_time );
$month_before = (int) date( "m", $base_time ) + 12 * (int) date( "Y", $base_time );
$month_after = (int) date( "m", $x_months_to_the_future ) + 12 * (int) date( "Y", $x_months_to_the_future );
if ($month_after > $months + $month_before)
$x_months_to_the_future = strtotime( date("Ym01His", $x_months_to_the_future) . " -1 day" );
return $x_months_to_the_future;
} //get_x_months_to_the_future()
// Tests
// =======
// returns 2009-02-28
echo date( "Y-m-d H:i:s", get_x_months_to_the_future( strtotime( '2009-01-31' ) ) ), "\n";
// returns 2008-02-29
echo date( "Y-m-d H:i:s", get_x_months_to_the_future( strtotime( '2008-01-31' ) ) ), "\n";
// returns 2009-09-30 12:00:00
echo date( "Y-m-d H:i:s", get_x_months_to_the_future( strtotime( '2009-05-31 12:00:00' ), 4 ) ), "\n";
?>
29-Dec-2008 08:13
Possible UTC (GMT) version of strtotime()
<?php
function gmstrtotime($my_time_string) {
return(strtotime($my_time_string . " UTC"));
}
?>
strtotime() assumes that anything you feed into it, uses the server's "relative" time zone.
By adding " UTC" to any input string, you make it "absolute".
18-Nov-2008 09:32
<?php
/**
* strToTime wrapper
*
* @param string[optional] $time
* @param int[optional] $now
* @return bool|int - returns false for '0000-00-00' and '0000-00-00 00:00:00'
*/
public static function myStrToTime($time = '', $now = null)
{
if('0000-00-00' == $time || '0000-00-00 00:00:00' == $time) {
return false;
}
//In version 5.2.6 strToTime returns int(-62169966000) for the 0 dates above
return strToTime($time, $now);
}
?>
15-Oct-2008 04:25
A simple way to work out someone's age in years:
<?php
$dob = '1984-09-04';
$age = date('Y') - date('Y', strtotime($dob));
if (date('md') < date('md', strtotime($dob))) {
$age--;
}
?>
10-Oct-2008 04:26
Just a quick note on dealing with non-standard strings:
If you attempt to parse single, random letters, strtotime() will give you apparently random output. Because strtotime() uses C's get_date() function, all dangling single letters are interpreted as military time zones. So, for example:
<?php
echo date('r', time())."<br />\n";
echo date('r', strtotime('L'))."<br />\n";
echo date('r', strtotime('1999L'));
?>
will return:
Fri, 10 Oct 2008 12:12:28 -0400
Thu, 09 Oct 2008 21:12:28 -0400
Sat, 09 Oct 1999 21:12:28 -0400
when executed in the UTC -5 timezone, because "L" is defined as UTC+11. J will return unix epoch, because it is not defined as a military time zone, while \t and \n both return the current time, as does a space. All other single characters return unix epoch, because they are not defined. The returned time is relative to the specified time, so the third example returns the current day and time in the year 1999, in timezone UTC +11.
25-Sep-2008 05:48
Some simple function to find all periods in dates list
<?php
function extract_periods($dates,$delimiter="="){
sort($dates);
$period=Array();
$date_from=$date_to="";
$k=0;
foreach ($dates as $key=>$value) {
if (empty($date_from)) $date_from=$value;
else {
$k++;
$tmp_date=strtotime("+ ".$k." day",strtotime($date_from));
if (date("Y-m-d", $tmp_date)!=$value) {
$tmp_date=strtotime("+ ".($k-1)." day",strtotime($date_from))
$date_to=date("Y-m-d",$tmp_date);
if ($date_from!=$date_to)
$period[]=$date_from.$delimiter.$date_to;
else
$period[]=$date_from;
$date_from=$value;
$k=0;
}
}
}
return $period;
}
Use:
$dates = Array(
"2008-09-30",
"2008-09-28",
"2008-09-26",
"2008-09-27",
"2008-09-25");
$periods = extract_periods($dates);
foreach ($periods as $value)
echo $value."<br />";
?>
Output:
2008-09-25=2008-09-28
2008-09-30
12-Sep-2008 06:35
I'm find some simple way to find all days between a couple of dates
(Все дни между двумя датами):
<?php
$dt=Array("27.01.1985","12.09.2008");
$dates=Array();
$i=0;
while (strtotime($dt[1])>=strtotime("+".$i." day",strtotime($dt[0])))
$dates[]=date("Y-m-d",strtotime("+".$i++." day",strtotime($dt[0])));
foreach ($dates as $value) echo $value."<br />";
?>
09-Sep-2008 09:39
A little function to add 2 time lenghts. Enjoy !
<?php
function AddPlayTime ($oldPlayTime, $PlayTimeToAdd) {
$pieces = split(':', $oldPlayTime);
$hours=$pieces[0];
$hours=str_replace("00","12",$hours);
$minutes=$pieces[1];
$seconds=$pieces[2];
$oldPlayTime=$hours.":".$minutes.":".$seconds;
$pieces = split(':', $PlayTimeToAdd);
$hours=$pieces[0];
$hours=str_replace("00","12",$hours);
$minutes=$pieces[1];
$seconds=$pieces[2];
$str = $str.$minutes." minute ".$seconds." second" ;
$str = "01/01/2000 ".$oldPlayTime." am + ".$hours." hour ".$minutes." minute ".$seconds." second" ;
// Avant PHP 5.1.0, vous devez comparer avec -1, au lieu de false
if (($timestamp = strtotime($str)) === false) {
return false;
} else {
$sum=date('h:i:s', $timestamp);
$pieces = split(':', $sum);
$hours=$pieces[0];
$hours=str_replace("12","00",$hours);
$minutes=$pieces[1];
$seconds=$pieces[2];
$sum=$hours.":".$minutes.":".$seconds;
return $sum;
}
}
$firstTime="00:03:12";
$secondTime="02:04:34";
$sum=AddPlayTime($firstTime,$secondTime);
if ($sum!=false) {
echo $firstTime." + ".$secondTime." === ".$sum;
}
else {
echo "failed";
}
?>
03-Sep-2008 03:50
Note that in some builds of PHP 5 doing the following may return unexpected results:
<?php
$server_date = date("Y-m-d"); // Assumed GMT 0
$timezone_offset = -10; // GMT -10
$date = date("Y-m-d", strtotime($server_date . " +" . $timezone_offset . " hours"));
echo $date; // prints 1969-12-31
?>
What it boils down to is the strtotime function accepting the time offset "+-10 hours", which confuses the function. To be safe be sure to check signs for offset values, and only add the plus (+) sign for non-negative offsets.
02-Sep-2008 10:51
strtotime returns time() for any string that begins with "eat" (case insensitive):
<?php
var_dump(strtotime('10 September 2000')); # int(968569200)
var_dump(strtotime('10 September 2000 asdfasdfasdf'));# bool(false)
var_dump(strtotime('asdfasdfasdf 10 September 2000'));# bool(false)
var_dump(strtotime('eat')); # int(1220358823)
var_dump(strtotime('eat asdfasdfasdf')); # int(1220358823)
var_dump(strtotime('asdfasdf eat')); # bool(false)
?>
You'll notice that 'eat.*' will always be a valid timestamp, so just using strtotime($is_it_a_time) will return a false positive on "eat a sandwich"
25-Aug-2008 02:34
Uncommenting the default timezone in the php.ini file also seems to do the trick in getting rid of the error messages:
[Date]
; Defines the default timezone used by the date functions
date.timezone = America/New_York
22-Aug-2008 04:31
"5.1.0 Now issues the E_STRICT and E_NOTICE time zone errors."
This little footnote represents a failure mode under common conditions, which is extremely frustrating. For example, this code ALWAYS returns an error on PHP 5:
<?php
ini_set('error_reporting', E_ALL|E_STRICT);
echo strtotime('Sun, 20 Jul 2008 23:34:07 GMT', time());
?>
Notice a standard HTTP-date was specified, so the PHP timezone setting will never affect the value returned by strtotime().
There is no documented workaround, and the suggested methods including date_default_timezone_get will cause the same errors. To make matters worse, those functions don't exist in older versions.
Based on my testing, it is necessary to provide PHP with a hard-coded timezone, any timezone at all, to prevent the error. Since the timezone has no affect on the results, I could use 'UTC' or 'America/Detroit' or any other valid string.
<?php
if (function_exists('date_default_timezone_set')) {
date_default_timezone_set('UTC');
}
echo strtotime('Sun, 20 Jul 2008 23:34:07 GMT', time());
?>
This is the only solution I have found so far.
Enjoy
Robert Chapin
Chapin Information Services
08-Aug-2008 01:48
strtotime() seems to treat dates delimited by slashes as m/d/y and dates delimited by dashes are treated as d-m-y.
<?php
print date('Y-m-d', strtotime("06/08/2008"));
?>
returns 2008-06-08
while
<?php
print date('Y-m-d', strtotime("06-08-2008"));
?>
returns 2008-08-06
Using PHP 5.2.6
23-Jul-2008 12:56
This function can be used to convert the timestamp generated by MySQL NOW() function into UNIX timestamp. Example:
Lets say MySQL NOW() returns '2008-07-23 06:07:42'.
<?php
$mysql_now='2008-07-23 06:07:42';
$time=strtotime($mysql_now);
echo date(d M y, H:i:s,$time);
//outputs: 23 Jul 08, 06:07:42
?>
Please note that the timestamp returned by mysql NOW() function may be the in the timezone of the server on which it was generated, and not always in GMT.
01-Jul-2008 07:48
It is worth noting, that strtotime() accepts ISO week date format (for example "2008-W27-2" is Tuesday of week 27 in 2008), so it can be easily used to get the date of a given week number.
<?php
function week($year, $week)
{
$from = date("Y-m-d", strtotime("{$year}-W{$week}-1")); //Returns the date of monday in week
$to = date("Y-m-d", strtotime("{$year}-W{$week}-7")); //Returns the date of sunday in week
return "Week {$week} in {$year} is from {$from} to {$to}.";
}
echo week(2008,27);
//Returns: Week 27 in 2008 is from 2008-06-30 to 2008-07-06.
?>
24-Jun-2008 07:59
When using a custom timestamp and adding a day to it, this works:
<?php strtotime("20080601 +1 day"); ?>
this does not:
<?php strtotime("20080601") + strtotime("+1 day"); ?>
that's because "+1 day" is another way to say the timestamp corresponding to tomorrow as of right now.
If you do it the wrong way, you'll end up with really bizarre dates in your loops. I was going from 20080601 to 19101019 to 19490412. What fun it was figuring that out. :)
10-Jun-2008 03:31
When using DB2 as an ODBC database source, the timestamps returned are in format "YYYY-MM-DD HH:MM:SS.mmmmmm" (m being microseconds).
Given that strtotime($str) is only accurate down to the second, you need to remove the microseconds from the string for it to work in strtotime.
For example:
<?php
$date = "2008-06-10 16:15:50.123456"; //as returned by DB2 SQL
$date = substr($date, 0, 19); //chop off the last 7 characters
//thus
$date == 1213110950;
//and
date('Y-m-d H-i-s', $date) == "2008-06-10 16:15:50";
?>
Note that if you wish to preserve the microseconds, you will need to do so before you chop them off of the string, but you don't need to include them or even pad timestamps with zeros when inserting them back into DB2.
10-Jun-2008 11:13
In complement to the my last post, roundTime(), here are two other functions. ceilTime() and floorTime() which round up or down to the specified increment respectively.
<?php
//RSS: 10/06/08 rounds a timestamp to the next specified increment
//only works for increments less than or equal to 1 hour
//EG: ceilTime("15 Minutes"); rounds the time right now to the next 15 minutes 11:12 rounds to 11:15
function ceilTime($increment, $timestamp=0)
{
if(!$timestamp) $timestamp = time();
$increment = strtotime($increment, 1) - 1;
$this_hour = strtotime(date("Y-m-d H:", strtotime("-1 Hour", $timestamp))."00:00");
$next_hour = strtotime(date("Y-m-d H:", strtotime("+1 Hour", $timestamp))."00:00");
$increments = array();
$differences = array();
for($i = $this_hour; $i <= $next_hour; $i += $increment)
{
if($i > $timestamp) return $i;
}
}
//RSS: 10/06/08 rounds a timestamp to the last specified increment
//only works for increments less than or equal to 1 hour
//EG: floorTime("15 Minutes"); rounds the time right now to the last 15 minutes 11:12 rounds to 11:00
function floorTime($increment, $timestamp=0)
{
if(!$timestamp) $timestamp = time();
$increment = strtotime($increment, 1) - 1;
$this_hour = strtotime(date("Y-m-d H:", strtotime("-1 Hour", $timestamp))."00:00");
$next_hour = strtotime(date("Y-m-d H:", strtotime("+1 Hour", $timestamp))."00:00");
$increments = array();
$differences = array();
for($i = $next_hour; $i >= $this_hour; $i -= $increment)
{
if($i < $timestamp) return $i;
}
}
?>
10-Jun-2008 10:41
If you want to round a timestamp to the closest specified increment, for example to the closest 15 minutes, then this function could help
Definition:
int roundTime ( string $increment[, int $timestamp] )
Parameters:
$increment is a string like you would for strtotime (but dont add a + or - to the front)
$timestamp (optional) the timestamp used to calculate the returned value.
Return Value:
returns timestamp
this function only works for increments less than or equal to an hour
Its not pretty but it works.
<?php
function roundTime($increment, $timestamp=0)
{
if(!$timestamp) $timestamp = time();
$increment = strtotime($increment, 1) - 1;
$this_hour = strtotime(date("Y-m-d H:", strtotime("-1 Hour", $timestamp))."00:00");
$next_hour = strtotime(date("Y-m-d H:", strtotime("+1 Hour", $timestamp))."00:00");
$increments = array();
$differences = array();
for($i = $this_hour; $i <= $next_hour; $i += $increment)
{
$increments []= $i;
$differences []= ($timestamp > $i)? $timestamp - $i : $i - $timestamp;
}
arsort($differences);
$key = array_pop(array_keys($differences));
return $increments[$key];
}
////////////
//EXAMPLE //
////////////
$result = roundtime("15 minutes");
echo date("H:i", time())." rounded to closest $increment is ".date("H:i", $result);
//11:24 rounded to closest 15 minutes is 11:30
?>
01-Jun-2008 02:56
Someone already reported an issue with finding the next month on the 31st of a month goes to two months down (essentially the next month with 31 days). There's a workaround for PHP 5.3+ here:
http://bugs.php.net/bug.php?id=44073
If you don't have 5.3 like me (and I can't update it) this code works:
<?php
// On the 31st of May:
strtotime("+1 month"); // Outputs July
strtotime("+1 month", strtotime(date("F") . "1")); // Outputs June
?>
In Engish: Figure out next month relative to the first of this month (date ("F") returns current month).
09-May-2008 07:08
Booyah! $time containing only numeric and space characters results in unexpected output (at least on Win2K server, not checked with linux).
<?php
echo date('d F Y', strtotime('2007')); // today's date (09 May 2008) displayed
echo date('d F Y', strtotime('01 2007')); // Warning: date(): Windows does not support dates prior to midnight (00:00:00), January 1, 1970
echo date('d F Y', strtotime('01 01 2007')); // same warning
echo date('d F Y', strtotime('01 Jan 2007')); // 01 January 2007
?>
No bug report submitted, I don't know enough about php and servers to know if this is expected behaviour or not.
31-Jan-2008 09:15
I found some different behaviors between PHP 4 and PHP 5. I have tested this on just two versions: PHP Version 5.2.3-1ubuntu6.3 and PHP Version 4.3.10-22.
Example 1:
<?php
$ts2 = strtotime("1st Thursday", $ts1)
var_dump($ts2)
// this works in PHP 4
// PHP 5 dumps bool(false)
?>
Example 2:
<?php
$ts2 = strtotime("first Thursday", $ts1)
var_dump($ts2)
// this works in PHP 4
// also works in PHP 5
?>
21-Jan-2008 01:56
As with each of the time-related functions, and as mentioned in the time() notes, strtotime() is affected by the year 2038 bug on 32-bit systems:
<?php
echo strtotime('13 Dec 1901 20:45:51'); // false
echo strtotime('13 Dec 1901 20:45:52'); // -2147483648
echo strtotime('19 Jan 2038 03:14:07'); // 2147483647
echo strtotime('19 Jan 2038 03:14:08'); // false
?>
10-Dec-2007 04:21
Be careful with spaces between the "-" and the number in the argument, for some PHP-installations...
<?php
strtotime("- 1 day") // ...with space - will ADD a day
strtotime("-1 day") // ...works perfect
?>
05-Dec-2007 06:42
Here is a list of differences between PHP 4 and PHP 5 that I have found
(specifically PHP 4.4.2 and PHP 5.2.3).
<?php
$ts_from_nothing = strtotime();
var_dump($ts_from_nothing);
// PHP 5
// bool(false)
// WARNING: Wrong parameter count...
// PHP 4
// NULL
// WARNING: Wrong parameter count...
// remember that unassigned variables evaluate to NULL
$ts_from_null = strtotime($null);
var_dump($ts_from_null)...
// PHP 5
// bool(false)
// throws a NOTICE: Undefined variable
// PHP 4
// current time
// NOTICE: Undefined variable $null...
// NOTICE: Called with empty time parameter...
$ts_from_empty = strtotime("");
var_dump($ts_from_empty);
// PHP 5
// bool(false)
// PHP 4
// current time
// NOTICE: Called with empty time parameter
$ts_from_bogus = strtotime("not a date");
var_dump($ts_from_bogus);
// PHP 5
// bool(false)
// PHP 4
// -1
?>
06-Nov-2007 09:50
strtotime() reads the timestamp in en_US format if you want to change the date format with this number, you should previously know the format of the date you are trying to parse. Let's say you want to do this :
<?php strftime("%Y-%m-%d",strtotime("05/11/2007")); ?>
It will understand the date as 11th of may 2007, and not 5th of november 2007. In this case I would use:
<?php
$date = explode("/","05/11/2007");
strftime("%Y-%m-%d",mktime(0,0,0,$date[1],$date[0],$date[2]));
?>
Much reliable but you must know the date format before. You can use javascript to mask the date field and, if you have a calendar in your page, everything is done.
Thank you.
01-Oct-2007 10:41
Here the workaround to the bug of strtotime() found in my previous comment on finding the exact date and time of "3 months ago of last second of this year", using mktime() properties on dates instead of strtotime(), and which seems to give correct results:
<?php
// check for equivalency
$basedate = strtotime("31 Dec 2007 23:59:59");
$timedate = mktime( 23, 59, 59, 1, 0, 2008 );
echo "$basedate $timedate "; // 1199141999 1199141999 : SO THEY ARE EQUIVALENT
// workaround, as mktime knows to handle properly offseted dates:
$date1 = mktime( 23, 59, 59, 1 - 3, 0, 2008 );
echo date("j M Y H:i:s", $date1); // 30 Sep 2007 23:59:59 CORRECT
?>
01-Oct-2007 08:36
Some surprisingly wrong results (php 5.2.0): date and time seem not coherent:
<?php
// Date: Default timezone Europe/Berlin (which is CET)
// date.timezone no value
$basedate = strtotime("31 Dec 2007 23:59:59");
$date1 = strtotime("-3 months", $basedate);
echo date("j M Y H:i:s", $date1); // 1 Oct 2007 23:59:59 WRONG
$basedate = strtotime("31 Dec 2007 23:59:59 CET");
$date1 = strtotime("-3 months", $basedate);
echo date("j M Y H:i:s", $date1); // 1 Oct 2007 23:59:59 WRONG
$basedate = strtotime("31 Dec 2007 23:59:59 GMT");
$date1 = strtotime("-3 months", $basedate);
echo date("j M Y H:i:s", $date1); // 1 Oct 2007 00:59:59 CORRECT
$basedate = strtotime("31 Dec 2007 22:59:59 GMT");
$date1 = strtotime("-3 months", $basedate);
echo date("j M Y H:i:s", $date1); // 1 Oct 2007 23:59:59 WRONG AGAIN
$basedate = strtotime("31 Dec 2007 00:00:00 GMT");
$date1 = strtotime("-3 months", $basedate);
echo date("j M Y H:i:s", $date1); // 1 Oct 2007 01:00:00 CORRECT
$basedate = strtotime("31 Dec 2007 00:00:00 CET");
$date1 = strtotime("-3 months", $basedate);
echo date("j M Y H:i:s", $date1); // 1 Oct 2007 00:00:00 WRONG AGAIN
$basedate = strtotime("31 Dec 2007 00:00:01");
$date1 = strtotime("-3 months", $basedate);
echo date("j M Y H:i:s", $date1); // 1 Oct 2007 00:00:01 WRONG AGAIN
?>
03-Sep-2007 02:33
Another inconsistency between versions:
<?php
print date('Y-m-d H:i:s', strtotime('today')) . "\n";
print date('Y-m-d H:i:s', strtotime('now')) . "\n";
?>
In PHP 4.4.6, "today" and "now" are identical, meaning the current timestamp.
In PHP 5.1.4, "today" means midnight today, and "now" means the current timestamp.
19-Jul-2007 01:13
A major difference in behavior between PHP4x and newer 5.x versions is the handling of "illegal" dates: With PHP4, strtotime("2007/07/55") gave a valid result that could be used for further calculations.
This does not work anymore at PHP5.xx (here: 5.2.1), instead something like strtotime("$dayoffset_relative_to_today days","2007/07/19") is to be used.
07-Jul-2007 05:47
when using strtotime("wednesday"), you will get different results whether you ask before or after wednesday, since strtotime always looks ahead to the *next* weekday.
strtotime() does not seem to support forms like "this wednesday", "wednesday this week", etc.
the following function addresses this by always returns the same specific weekday (1st argument) within the *same* week as a particular date (2nd argument).
<?php
function weekday($day="", $now="") {
$now = $now ? $now : "now";
$day = $day ? $day : "now";
$rel = date("N", strtotime($day)) - date("N");
$time = strtotime("$rel days", strtotime($now));
return date("Y-m-d", $time);
}
?>
example use:
weekday("wednesday"); // returns wednesday of this week
weekday("monday, "-1 week"); // return monday the in previous week
ps! the ? : statements are included because strtotime("") without gives 1 january 1970 rather than the current time which in my opinion would be more intuitive...
01-Jul-2007 02:54
To calculate the last Friday in the current month, use strtotime() relative to the first day of next month:
<?php
$lastfriday=strtotime("last Friday",mktime(0,0,0,date("n")+1,1));
?>
If the current month is December, this capitalises on the fact that the mktime() function correctly accepts a month value of 13 as meaning January of the next year.
01-Jun-2007 03:10
Note about strtotime() when trying to figure out the NEXT month...
strtotime('+1 months'), strtotime('next month'), and strtotime('month') all work fine in MOST circumstances...
But if you're on May 31 and try any of the above, you will find that 'next month' from May 31 is calculated as July instead of June....
13-May-2007 03:41
One more difference between php 4 and 5 (don't know when they changed this) but the string 15 EST 5/12/2007 parses fine with strtotime in php 4, but returns the 1969 date in php 5. You need to add :00 to make it 15:00 so php can tell those are hours. There's no change in php 4 when you do this.
08-Apr-2007 01:31
This function inputs a date sting and outputs an integer that is the internal representation of days that spreadsheets use. Post this value into a cell, then format that cell as a Date.
<?php
function conv_to_xls_date($Date) {
// Returns the Excel/Calc internal date integer from either an ISO date YYYY-MM-DD or MM/DD/YYYY formats.
return (int) (25569 + (strtotime("$Date 12:00:00") / 86400));
}
?>
example:
<?php
$Date = "04-07-2007";
$Days = conv_to_xls_date($Date);
?>
$Days will contain 39179
SQL datetime columns have a much wider range of allowed values than a UNIX timestamp, and therefore this function is not safe to use to convert a SQL datetime column to something usable in PHP4. Year 9999 is the limit for MySQL, which obviously exceeds the UNIX timestamp's capacity for storage. Also, dates before 1970 will cause the function to fail (at least in PHP4, don't know about 5+), so for example my boss' birthday of 1969-08-11 returned FALSE from this function.
[red. The function actually supports it since PHP 5.1, but you will need to use the new object oriented methods to use them. F.e:
<?php
$date = new DateTime('1969-08-11');
echo $date->format('m d Y');
?>
]
09-Feb-2007 08:29
Regarding the "NET" thing, it's probably parsing it as a time-zone. If you give strtotime any timezone string (like PST, EDT, etc.) it will return the time in that time-zone.
In any case, you shouldn't use strtotime to validate dates. It can and will give incorrect results. As just one shining example:
Date: 05/01/2007
To most Americans, that's May 1st, 2007. To most Europeans, that's January 5th, 2007. A site that needs to serve people around the globe cannot use strtotime to validate or even interpret dates.
The only correct way to parse a date is to mandate a format and check for that specific format (preg_match will make your life easy) or to use separate form fields for each component (which is basically the same thing as mandating a format).
16-Jan-2007 10:47
A hint not to misunderstand the second parameter:
The parameter "[, int now]" is only used for strings which describe a time difference to another timestamp.
It is not possible to use strtotime() to calculate a time difference by passing an absolute time string, and another timestamp to compare to!
Correct:
<?php
$day_before = strtotime("+1 day", $timestamp);
# result is a timestamp relative to another
?>
Wrong:
<?ph