PHP 5.4.31 Released

strtotime

(PHP 4, PHP 5)

strtotimeParse about any English textual datetime description into a Unix timestamp

Açıklama

int strtotime ( string $time [, int $now = time() ] )

The function expects to be given a string containing an 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.

Each parameter of this function uses the default time zone unless a time zone is specified in that parameter. Be careful not to use different time zones in each parameter unless that is intended. See date_default_timezone_get() on the various ways to define the default time zone.

Değiştirgeler

time

Bir tarih/zaman dizgesi. Geçerli biçemler Tarih ve Zaman Biçemleri bölümünde açıklanmıştır.

now

The timestamp which is used as a base for the calculation of relative dates.

Dönen Değerler

Returns a timestamp on success, FALSE otherwise. Previous to PHP 5.1.0, this function would return -1 on failure.

Hatalar/İstisnalar

Bir tarih/zaman işlevine yapılan her çağrı eğer zaman dilimi ayarı geçerli değilse bir E_NOTICE üretir. Ve/veya eğer sistem ayarları veya TZ ortam değişkeni kullanılıyorsa bir E_STRICT veya bir E_WARNING iletisi üretir. Ayrıca bakınız: date_default_timezone_set()

Sürüm Bilgisi

Sürüm: Açıklama
5.3.0 Prior to PHP 5.3.0, relative time formats supplied to the time argument of strtotime() such as this week, previous week, last week, and next week were interpreted to mean a 7 day period relative to the current date/time, rather than a week period of Monday through Sunday.
5.3.0 Prior to PHP 5.3.0, 24:00 was not a valid format and strtotime() returned FALSE.
5.2.7 In PHP 5 prior to 5.2.7, requesting a given occurrence of a given weekday in a month where that weekday was the first day of the month would incorrectly add one week to the returned timestamp. This has been corrected in 5.2.7 and later versions.
5.1.0 Now returns FALSE on failure, instead of -1.
5.1.0

Zaman dilimi hatalarında artık E_STRICT ve E_NOTICE çıktılanıyor.

5.0.2 In PHP 5 up to 5.0.2, "now" and other relative times are wrongly computed from today's midnight. This differs from other versions where it is correctly computed from current time.
5.0.0 Microseconds began to be allowed, but they are ignored.
4.4.0 In PHP versions prior to 4.4.0, "next" is incorrectly computed as +2. A typical solution to this is to use "+1".

Örnekler

Örnek 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";
?>

Örnek 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);
}
?>

Notlar

Bilginize:

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).

Bilginize:

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.

For 64-bit versions of PHP, the valid range of a timestamp is effectively infinite, as 64 bits can represent approximately 293 billion years in either direction.

Bilginize:

Dates in the m/d/y or d-m-y formats are disambiguated by looking at the separator between the various components: if the separator is a slash (/), then the American m/d/y is assumed; whereas if the separator is a dash (-) or a dot (.), then the European d-m-y format is assumed.

To avoid potential ambiguity, it's best to use ISO 8601 (YYYY-MM-DD) dates or DateTime::createFromFormat() when possible.

Bilginize:

Using this function for mathematical operations is not advisable. It is better to use DateTime::add() and DateTime::sub() in PHP 5.3 and later, or DateTime::modify() in PHP 5.2.

Ayrıca Bakınız

add a note add a note

User Contributed Notes 73 notes

up
107
sam at frontiermedia dot net dot au
3 years ago
I've had a little trouble with this function in the past because (as some people have pointed out) you can't really set a locale for strtotime. If you're American, you see 11/12/10 and think "12 November, 2010". If you're Australian (or European), you think it's 11 December, 2010. If you're a sysadmin who reads in ISO, it looks like 10th December 2011.

The best way to compensate for this is by modifying your joining characters. Forward slash (/) signifies American M/D/Y formatting, a dash (-) signifies European D-M-Y and a period (.) signifies ISO Y.M.D.

Observe:

<?php
echo date("jS F, Y", strtotime("11.12.10"));
// outputs 10th December, 2011

echo date("jS F, Y", strtotime("11/12/10"));
// outputs 12th November, 2010

echo date("jS F, Y", strtotime("11-12-10"));
// outputs 11th December, 2010 
?>

Hope this helps someone!
up
16
Stefan Kunstmann
4 years ago
UK dates (eg. 27/05/1990) won't work with strotime, even with timezone properly set.
However, if you just replace "/" with "-" it will work fine.
<?php
$timestamp
= strtotime(str_replace('/', '-', '27/05/1990'));
?>
up
8
me at will morgan dot co dot you kay
1 year ago
For negative UNIX timestamps, strtotime seems to return the literal you passed in, or it may try to deduct the number of seconds from today's date.

To work around this behaviour, it appears that the same behaviour as described in the DateTime classes applies:

http://php.net/manual/en/datetime.construct.php

Specifically this line here (in the EN manual):

> The $timezone parameter and the current timezone are ignored when the $time parameter either is a UNIX timestamp (e.g. @946684800) or specifies a timezone (e.g. 2010-01-28T15:00:00+02:00).

Therefore strtotime('@-1000') returns 1000 seconds before the epoch.

Hope this helps.
up
8
orel16 at ya dot ru
5 years ago
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 />";
?>
up
17
jdiamond at taoti dot com
2 years ago
To avoid frustrating confusion I recommend always calling
date_default_timezone_set('UTC') before using strtotime().

Because the UNIX Epoch is always in UTC; you will most likely output the wrong time if you do not do this.

Cheers
up
13
michal dot kocarek at brainbox dot cz
4 years ago
strtotime() also returns time by year and weeknumber. (I use PHP 5.2.8, PHP 4 does not support it.) Queries can be in two forms:
- "yyyyWww", where yyyy is 4-digit year, W is literal and ww is 2-digit weeknumber. Returns timestamp for first day of week (for me Monday)
- "yyyy-Www-d", where yyyy is 4-digit year, W is literal, ww is 2-digit weeknumber and dd is day of week (1 for Monday, 7 for Sunday)

<?php
// Get timestamp of 32nd week in 2009.
strtotime('2009W32'); // returns timestamp for Mon, 03 Aug 2009 00:00:00
// Weeknumbers < 10 must be padded with zero:
strtotime('2009W01'); // returns timestamp for Mon, 29 Dec 2008 00:00:00
// strtotime('2009W1'); // error! returns false

// See timestamp for Tuesday in 5th week of 2008
strtotime('2008-W05-2'); // returns timestamp for Tue, 29 Jan 2008 00:00:00
?>

Weeknumbers are (probably) computed according to ISO-8601 specification, so doing date('W') on given timestamps should return passed weeknumber.
up
6
peterson at npd dot ufsc dot br
3 years ago
A function to add two times, without using the explode function

<?php

$hour_one
= "01:20:20";
$hour_two = "05:50:20";
$h strtotime($hour_one);
$h2 = strtotime($hour_two);

$minute = date("i", $h2);
$second = date("s", $h2);
$hour = date("H", $h2);

echo
"<br>";

$convert = strtotime("+$minute minutes", $h);
$convert = strtotime("+$second seconds", $convert);
$convert = strtotime("+$hour hours", $convert);
$new_time = date('H:i:s', $convert);

echo
$new_time;

?>
up
9
elad dot yosifon at gmail dot com
2 years ago
This example shows common methods to get a timestamp from $year,$month,$day variables.
strtotime() with implode() seems to be the fastest way (performance wise..)

<?php

   
function logTime($start,$end,$functionName){
        echo
"$functionName() = ".(float)($end-$start)*(60*60)."<br>";
    }

   
$day = '01';    $month = '01';    $year = '2000';

   
$time = array();
   
$timestamps = array();
   
$time[] = array(microtime(true),'start');

   
$timestamps[] = mktime(0,0,0,$month,$day,$year);
   
$time[] = array(microtime(true),'mktime');

   
$timestamps[] = strtotime($year.'-'.$month.'-'.$day);
   
$time[] = array(microtime(true),'strtotime');

   
$timestamps[] = strtotime(implode('-', array($year, $month, $day)));
   
$time[] = array(microtime(true),'strtotime_Array');

   
$timestamps[] = date_create_from_format('!Y-m-d', $year.'-'.$month.'-'.$day)->getTimestamp();
   
$time[] = array(microtime(true),'date_create_from_format');

   
$timestamps[] = date_create_from_format('!Y-m-d', implode('-', array($year, $month, $day)))->getTimestamp();
   
$time[] = array(microtime(true),'date_create_from_format_Array');

   
$timestamps[] = DateTime::createFromFormat('!Y-m-d', $year.'-'.$month.'-'.$day)->getTimestamp();
   
$time[] = array(microtime(true),'DateTime');

   
$timestamps[] = DateTime::createFromFormat('!Y-m-d', implode('-', array($year, $month, $day)))->getTimestamp();
   
$time[] = array(microtime(true),'DateTime_Array');

    foreach (
$time as $key=>$value) {
        if(
end($time) == $value){}else{
           
logTime($value[0],$time[$key+1][0],$time[$key+1][1]);
        }
    }

   
// just to show that all timestamps are correct
   
var_dump($timestamps);
?>
up
9
Michael Muryn (MickoZ)
2 years ago
This comment apply to PHP5+

We can now do thing like this with strtotime:
<?php
$weekMondayTime
= strtotime('Monday this week');
?>
However this works based on a week starting Sunday.  I do not know if we can tweak this PHP behavior, anyone know?

If you want the timestamp of the start of the ISO Week (i.e. on Monday) as defined by ISO 8601, you can use this one liner:
<?php
$isoWeekStartTime
= strtotime(date('o-\\WW')); // {isoYear}-W{isoWeekNumber}
?>

You can also find out the start of week of any time and format it into an ISO date with another one liner like this:
<?php
$isoWeekStartDate
= date('Y-m-d', strtotime(date('o-\\WW', $time)));
?>

For more information about ISO-8601 and ISO week date:
http://en.wikipedia.org/wiki/ISO_8601#Week_dates
http://en.wikipedia.org/wiki/ISO_week_date
up
9
joris dot landman at gmail dot com
5 years ago
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".
up
5
nan at ladyslipperwebs dot com
5 years ago
A great little function to see if dates chosen are more than three months apart and if they are, change the end date to three months from the begin date. This is easy to change.

<?php
function daysDifference($endDate, $startDate)
{
   
$startTS = strtotime($startDate);
   
$endTS = strtotime($endDate);
   
$maxTS = strtotime($startDate.' + 3 months');   
    if(
$endTS > $maxTS) {
         
$endTS = $maxTS;
    }
   
$endDate = date('Y-m-d', $endTS); 
    return
$endDate;
}
?>
up
17
kumar AT swatantra.info Swatantra Kumar
1 year ago
The "+1 month" issue with strtotime
===================================
As noted in several blogs, 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
echo date( "Y-m-d", strtotime( "2009-01-31 +1 month" ) ); // PHP:  2009-03-03
echo date( "Y-m-d", strtotime( "2009-01-31 +2 month" ) ); // PHP:  2009-03-31
?>

<?php
SELECT DATE_ADD
( '2009-01-31', INTERVAL 1 MONTH ); // MySQL:  2009-02-28
?>
up
5
orel16 at ya dot ru
5 years ago
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
up
3
kyle at frozenonline dot com
10 years ago
I was having trouble parsing Apache log files that consisted of a time entry (denoted by %t for Apache configuration). An example Apache-date looks like: [21/Dec/2003:00:52:39 -0500]

Apache claims this to be a 'standard english format' time. strtotime() feels otherwise.

I came up with this function to assist in parsing this peculiar format.

<?php
function from_apachedate($date)
{
        list(
$d, $M, $y, $h, $m, $s, $z) = sscanf($date, "[%2d/%3s/%4d:%2d:%2d:%2d %5s]");
        return
strtotime("$d $M $y $h:$m:$s $z");
}
?>

Hope it helps anyone else seeking such a conversion.
up
18
cristinawithout
2 years ago
WARNING when using "next month", "last month", "+1 month",  "-1 month" or any combination of +/-X months. It will give non-intuitive results on Jan 30th and 31st.

As described at : http://derickrethans.nl/obtaining-the-next-month-in-php.html

<?php
$d
= new DateTime( '2010-01-31' );
$d->modify( 'next month' );
echo
$d->format( 'F' ), "\n";
?>

In the above, using "next month" on January 31 will output "March" even though you might want it to output "February". ("+1 month" will give the same result. "last month", "-1 month" are similarly affected, but the results would be seen at beginning of March.)

The way to get what people would generally be looking for when they say "next month" even on Jan 30 and Jan 31 is to use "first day of next month":

<?php
$d
= new DateTime( '2010-01-08' );
$d->modify( 'first day of next month' );
echo
$d->format( 'F' ), "\n";
?>

<?php
$d
= new DateTime( '2010-01-08' );
$d->modify( 'first day of +1 month' );
echo
$d->format( 'F' ), "\n";
?>
up
6
Annomoys
3 years ago
Strtotime() can be used to loop through date range.
as follows

<?php
$start
= strtotime('2009-02-01');
$end = strtotime('2009-03-10');
$date = $start;
while(
$date < $end)
{

  
//write your code here
  
$date = strtotime("+1 day", $date);(counter)

}

?>
up
4
A dot Lepe dev+php at alepe dot com
4 years ago
This is a quick function to calculate the "working days" within a period of one year. "Working days" are those without weekends and without the holidays specified in the $holiday array. I left for the reader its implementation for more than 1 year.
<?php
/*
* Author: Alberto Lepe
* Calculates the working days from today to an specific date.
* NOTE: counting starts from today
* @pararm to_date: timestamp
*/
function get_working_days($to_date) {
   
$holidays = array(
       
1 => array(10), //2011 ...
       
2 => array(11),
       
3 => array(21), //... 2011
       
4 => array(29,30), //2010 ...
       
5 => array(3,4,5),
       
6 => array(),
       
7 => array(19),
       
8 => array(11,12,13),
       
9 => array(20,23),
      
10 => array(11),
      
11 => array(3,23),
      
12 => array(23) //... 2010
   
);

    for(
$to_date, $w = 0, $i = 0, $x = time(); $x < $to_date; $i++, $x = strtotime("+$i day")) {
       if(
date("N",$x) < 6 &! in_array(date("j",$x),$holidays[date("n",$x)])) $w++;
    }
    return
$w;
}

//Usage:
echo get_working_days(strtotime("2011-01-08"));
?>
up
10
katylava at gmail dot com
4 years ago
You should play around with strtotime() before you decide what it can't do.  for example:

<?php

# on 2/8/2010
date('m/d/y', strtotime('first day')); # 02/01/10
date('m/d/y', strtotime('last day')); # 02/28/10
date('m/d/y', strtotime('last day next month')); # 03/31/10
date('m/d/y', strtotime('last day last month')); # 01/31/10
date('m/d/y', strtotime('2009-12 last day')); # 12/31/09 - this doesn't work if you reverse the order of the year and month
date('m/d/y', strtotime('2009-03 last day')); # 03/31/09
date('m/d/y', strtotime('2009-03')); # 03/01/09
date('m/d/y', strtotime('last day of march 2009')); # 03/31/09
date('m/d/y', strtotime('last day of march')); # 03/31/10
?>
up
4
will at mooloop dot com
5 years ago
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--;
}
?>
up
8
info at jesperveldhuizen dot com
2 years ago
There is a change in the strtotime function...

<?php

echo date('Y', strtotime('0000-00-00 00:00:00'));

/*
PHP 5.3.3
returns: -0001

PHP 5.2.10
returns: 1970
*/

?>
up
8
silveraxe at gmail dot com
2 years ago
This date is interpreted as American date (MM/DD/YYYY):
$date = "06/10/2011 14:28"; // Oct 10, 2011

This date is interpreted as European date (DD/MM/YYYY):
$otherDate = "06-10-2011 14:28"; // Jun 10, 2011

That's why you see those differences.
up
2
fuhrysteve at gmail dot com
5 years ago
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";

?>
up
7
Bandit
7 years ago
So I wanted a little function to output an easy to read but inaccurate date. I came up with the following (probably very inefficient) little function;

<?php
   
function ezDate($d) {
       
$ts = time() - strtotime(str_replace("-","/",$d));
       
        if(
$ts>31536000) $val = round($ts/31536000,0).' year';
        else if(
$ts>2419200) $val = round($ts/2419200,0).' month';
        else if(
$ts>604800) $val = round($ts/604800,0).' week';
        else if(
$ts>86400) $val = round($ts/86400,0).' day';
        else if(
$ts>3600) $val = round($ts/3600,0).' hour';
        else if(
$ts>60) $val = round($ts/60,0).' minute';
        else
$val = $ts.' second';
       
        if(
$val>1) $val .= 's';
        return
$val;
    }
?>

Then I use it as follows;

<?php
   
echo ucwords(ezDate('2006-09-07 18:42:00')).' Ago';
?>

Which would output;

    2 Months Ago

I add an acronym tag around the output also, so my users can mouse-over for the exact date.

Hope it helps someone!
up
5
flexibill2001 at hotmail dot com
4 years ago
lot of people said that there is bug in strtotime method like given in this example:

<?php echo date( "Y-m-d", strtotime( "2009-01-31 +1 months" ) )."<br>"; ?>

this gives 03-03-2009 instead of 28-02-2009

here is work arround for this bug.

<?php
/// n=no of months  , $y =year, $m = month, $d = day , $t = + or -

function NewMonthDate($n,$y,$m,$d,$t)
    {
               
        for(
$i=1; $i <= $n; $i++)
            {
            if(
$t=="+")
                {
               
$pmonth=$m+$i;   
                }
            if(
$t=="-")
                {
               
$pmonth=$m-$i;   
                }
       
       
$pyear=$y;
       
$aa=1;
       
       
       
/////////////////this will show lastmonth//////////////
       
$lastmonth = mktime(0, 0, 0, $pmonth, $aa$pyear);
       
        
$smonth=date("m",$lastmonth);
        
$syear=date("Y",$lastmonth);
        
$ndays=date("t",$lastmonth);
       
$valarray=array($smonth,$syear,$ndays);
               
       
$mm=$mm+$ndays;
       
            }
           
       
$basedate="$pyear-$m-$d";
       
$date2 = strtotime("$basedate $t$mm days");   
       
       
$date1=date("d-m-Y",$date2);
        return 
$date1;
           
    }  
////

$n=1;
$y=2009;
$m=01;
$d=31;
$t="+";

$rr=NewMonthDate($n,$y,$m,$d,$t);
print_r($rr);
?>
up
5
php at davidstockton dot com
5 years ago
Adding a note to an already long page:

Try to be as specific as you can with the string you pass in.  For example

<?php
echo date('F', strtotime('February'));
?>

is not specific enough.  Depending on the day of the month, you may get a different response.  For a non-leap year, you'll get March if the _current day of the month_ is the 29th, 30th or 31st.  If it's a leap year, you'll get March on the 30th or 31st of the month.  The same thing will happen on the 31st of any month when you pass in the name of any month with less than 31 days.  This happens because the strtotime() function will fill in missing parts from the current day.

Assuming today is July 31, the timestamp returned by strtotime('February') will ultimately be seen as February 31 (non-existant obviously), which then is interpreted as March 3, thus giving a month name of March.

Interestingly, adding the year or the day will give you back the expected month.
up
3
agok at yandex dot ru
11 months ago
//get first and last day of quarter for some date
$date = new DateTime('2013-01-01');
echo
$date->modify('-'.(($date->format('n') - 1)%3).' month')->modify('first day of this month')->format('Y-m-d');
echo '<br/>';
echo
$date->modify('+2 month')->modify('last day of this month')->format('Y-m-d');
up
6
Anonymous
4 years ago
This function DOES NOT work from left-to-right as one would think. This function parses the string as a whole, then applies the intervals by size (year, month, ...). Take the following example:

<?php
$Date
= strtotime('2011-02-22'); // February 22nd, 2011. 28 days in this month, 29 next year.
echo date('n/j/Y', strtotime('+1 year, +7 days', $Date)); // add 1 year and 7 days. prints 2/29/2012
echo "<br />";
echo
date('n/j/Y', strtotime('+7 days, +1 year', $Date)); // add 7 days and 1 year, but this also prints 2/29/2012
echo "<br />";
echo
date('n/j/Y', strtotime('+1 year', strtotime('+7 days', $Date))); // this prints 3/1/2012, what the 2nd would do if it was left-to-right
?>
up
6
akniep at rayo dot info
5 years ago
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";

?>
up
4
gffabio at hotmail dot com
5 months ago
una solucion al para saber el primer y ultimo dia del mes siguiente
<?php
$fecha
= '2014-01-31';
//resultado incorrecto
echo date('Y-m-01',strtotime("$fecha next month")).'<br>';//2014-03-01
echo date('Y-m-t',strtotime("$fecha next month")).'<br>';//2014-03-31
//correcto
echo date('Y-m-01',strtotime("$fecha last day of next month")).'<br>';//2014-02-01
echo date('Y-m-t',strtotime("$fecha last day of next month")).'<br>';//2014-02-28

$fecha = '2014-05-31';
//resultado incorrecto
echo date('Y-m-01',strtotime("$fecha next month")).'<br>';//2014-07-01
echo date('Y-m-t',strtotime("$fecha next month")).'<br>';//2014-07-31
//correcto
echo date('Y-m-01',strtotime("$fecha last day of next month")).'<br>';//2014-06-01
echo date('Y-m-t',strtotime("$fecha last day of next month"));//2014-06-28
?>
up
3
marcodemaio at vanylla dot it
3 years ago
NOTE: strttotime returns wrong values (or guessed values) when the Week day does not macth the date.
Simple example:

<?php
$d1
= strtotime("26 Oct 0010 12:00:00 +0100");
$d2 = strtotime("Tue, 26 Oct 0010 12:00:00 +0100");
$d3 = strtotime("Sun, 26 Oct 0010 12:00:00 +0100"); //But Oct 26 is a Tuesday, NOT a Sunday.

echo $d1; //ok 1288090800 that is "26 Ott 2010 - 11:00";
echo $d2; //ok 1288090800 that is "26 Ott 2010 - 11:00";
echo $d3; //WRONG! 1288522800 that is "31 Ott 2010 - 11:00";
?>

Sometime I found RSS feeds that contains week days that do not match the date.

A possible solution is to remove useless week day before passing the date string into strtime, example:

<?php
   $date_string
= "Sun, 26 Oct 0010 12:00:00 +0100";
   if( (
$comma_pos = strpos($date_string, ',')) !== FALSE )
     
$date_string = substr($date_string, $comma_pos + 1);
  
$d3 = strtotime($date_string);
?>
up
7
cryogen at mac dot com
10 years ago
Append the string "GMT" to all of your datetimes pulled from MySQL or other database that store date-times in the format "yyyy-mm-dd hh:ii:ss" just prior to converting them to a unix timestamp with strtotime().  This will ensure you get a valid GMT result for times during daylight savings.

EXAMPLE:
<?php
$date_time1
= strtotime("2004-04-04 02:00:00"); // returns bad value -1 due to DST
$date_time2 = strtotime("2004-04-04 02:00:00 GMT"); // works great!
?>
up
5
viper7 at viper-7 dot com
5 years ago
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
up
4
Tim
3 years ago
Unlike "yesterday 14:00", "14:00 yesterday" will return 00:00 of yesterday.  Here's a function that'll fix that:

<?php
function fix_strtotime($date)
{
    if(
preg_match('/([012]?[0-9]?:[0-5]{1}\d\s*[aA|pP]?[mM]?)(\s+)(.+)/', $date, $matches))
    {
        return
strtotime($matches[3] . $matches[2] . $matches[1]);
    }
    return
strtotime($date);
}
echo
date('Y-m-d H:i:s', fix_strtotime('14:00 yesterday')); // 2010-09-17 14:00:00
echo date('Y-m-d H:i:s', fix_strtotime('yesterday 14:00')); // 2010-09-17 14:00:00
?>
up
2
giacomo at cinquepunti dot it
2 years ago
this function allow the use of native strtotime with dates before 1970 (and before 1900) even in Windows

<?php
function safe_strtotime($string)
{
    if(!
preg_match("/\\d{4}/", $string, $match)) return null; //year must be in YYYY form
   
$year = intval($match[0]);//converting the year to integer
   
if($year >= 1970) return date("Y-m-d", strtotime($string));//the year is after 1970 - no problems even for Windows
   
if(stristr(PHP_OS, "WIN") && !stristr(PHP_OS, "DARWIN")) //OS seems to be Windows, not Unix nor Mac
   
{
       
$diff = 1975 - $year;//calculating the difference between 1975 and the year
       
$new_year = $year + $diff;//year + diff = new_year will be for sure > 1970
       
$new_date = date("Y-m-d", strtotime(str_replace($year, $new_year, $string)));//replacing the year with the new_year, try strtotime, rendering the date
       
return str_replace($new_year, $year, $new_date);//returning the date with the correct year
   
}
    return
date("Y-m-d", strtotime($string));//do normal strtotime
}
?>
up
3
ariunbayar
4 years ago
if you looking for next 31 here it is for PHP5.3
<?php
$d
= 31;
$now = strtotime('2010-06-02');
while (
date('t', $now) < $d){
 
$now = strtotime('last day of next month', $now);
}
echo
date('Y-m-'.$d, $now);
?>
will output "2010-07-31".
up
3
kooshal at live dot com
4 years ago
when using PHP 5.3, you must use date_default_timezone_set() to set the time zone otherwise you will get warning similar to this (if you have display_errors=On)—

Warning: date() [function.date]: It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected 'Asia/Dubai' for '4.0/no DST' instead in path/to/php/script.php
on line ##

Example:
date_default_timezone_set('Indian/Mauritius');

For a list of supported timezones in PHP, see http://www.php.net/manual/en/timezones.php
up
2
x at xero dot nu
3 years ago
strtotime is awesome for converting dates.
in this example i will make an RSS date, an
ATOM date, then convert them to a human
readable m/d/Y dates.

<?php
$rss
= date("r");
$atom = date("c");
$human1 = date('m/d/Y', strtotime($rss));
$human2 = date('m/d/Y', strtotime($atom));

echo
$rss."<br />".$atom."<br />".$human1."<br />".$human2;
?>
up
4
jaymin at gmx dot net
5 years ago
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
up
2
Killermonk
5 years ago
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
up
2
raph
5 years ago
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";
}
?>
up
2
richard at happymango dot me dot uk
6 years ago
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
?>

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;
    }
}

?>
up
1
Zoe Blade
5 years ago
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.]
up
5
bbutts at stormcode dot net
5 years ago
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.
up
2
PHP_Chimp
5 years ago
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.
up
2
andrew dot myers at civicwifi dot com
6 years ago
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

?>
up
1
nyctimus at yahoo dot com
3 years ago
strtotime() produces different output on 32 and 64 bit systems running PHP 5.3.3 (as mentioned previously).  This affects the "zero date" ("0000-00-00 00:00:00") as well as dates outside the traditional 32 date range.

strtotime("0000-00-00 00:00:00") returns FALSE on a 32 bit system.
strtotime("0000-00-00 00:00:00") returns -62169955200 on a 64 bit system.
up
1
Anonymous
5 months ago
Be aware that you cannot rely on this function alone to validate a date, as it will accept insane dates like the 31st of February.

Also, the '... week' functionality by itself may not do what you expect. If used on a Sunday, 'next week' will not return a timestamp of the next Monday, but of the Monday after that. Similarly, a timestamp for the Monday of the current week is returned when 'previous/last week' is used and 'this week' returns a stamp of the Monday of the next week (i.e. the following day). This is not the 'week starts on Sunday' effect, as that would mean all the timestamps returned would have to be on a Sunday and none of them are.
up
1
Christian L.
7 months ago
To get the start of the current week this code works fine when the week starts on Sundays.

<?php strtotime('this Monday'); ?>

To get the timestamp of the start of a week starting on Mondays (as defined by ISO 8601) this shoud do the trick.

<?php strtotime('next Monday -1 week'); ?>
up
0
Anonymous
4 months ago
<?php
# strtotime() function with param "now" work only with UTC
# time zone (GMT) Grinvich, but param "midnight" work with
# local time zone

date_default_timezone_set("Europe/Kiev");
echo
"Kiev:".strtotime("now");
echo
"<br><br>";

date_default_timezone_set("America/New_York");
echo
"New-York:".strtotime("now");
echo
"<br><br>";
date_default_timezone_set("UTC");
echo
"UTC:".strtotime("now");
echo
"<br>==========================<br>";

date_default_timezone_set("Europe/Kiev");
echo
"Kiev:".strtotime("midnight");
echo
"<br><br>";

date_default_timezone_set("America/New_York");
echo
"New-York:".strtotime("midnight");
echo
"<br><br>";
date_default_timezone_set("UTC");
echo
"UTC:".strtotime("midnight");
echo
"<br><br>";
?>

result:
Kiev:1394781415

New-York:1394781415

UTC:1394781415
==========================
Kiev:1394748000

New-York:1394769600

UTC:1394755200
up
0
peixoto at live dot com
4 months ago
<?php strtotime('-5 weeks monday') ?> returns the monday of 5 weeks ago.
up
0
brokndodge at yahoo dot com
6 months ago
If you want to add or subtract a strtotime to/from a strtotime:
<?php
$d
= strtotime('-1 day',strtotime("first day of last month"))
echo
$d
?>
up
0
les dot mc dot pls at gmail dot com
9 months ago
@lazzich
just wanted to say that by coincidence i commented out the:

//$date(2011/07/15);
//$time(15:00:00);

and the result was 16,000 days ago...

Happy 16,000 day anniversary of
01/01/1970 everyone!!!
up
-1
a dot dyudyun at gmail dot com
4 months ago
<?php
# strtotime() function with param "now" work only with UTC
# time zone (GMT) Grinvich, but param "midnight" work with
# local time zone

date_default_timezone_set("Europe/Kiev");
echo
"Kiev:".strtotime("now");
echo
"<br><br>";

date_default_timezone_set("America/New_York");
echo
"New-York:".strtotime("now");
echo
"<br><br>";
date_default_timezone_set("UTC");
echo
"UTC:".strtotime("now");
echo
"<br>==========================<br>";

date_default_timezone_set("Europe/Kiev");
echo
"Kiev:".strtotime("midnight");
echo
"<br><br>";

date_default_timezone_set("America/New_York");
echo
"New-York:".strtotime("midnight");
echo
"<br><br>";
date_default_timezone_set("UTC");
echo
"UTC:".strtotime("midnight");
echo
"<br><br>";
?>

result:
Kiev:1394781415

New-York:1394781415

UTC:1394781415
==========================
Kiev:1394748000

New-York:1394769600

UTC:1394755200
up
0
darylblake at gmail dot com
2 years ago
I was doing work with cisco phone systems, and thy record their times as NTP Format.

strtotime() doesnt process the whole NTP timestamp, off the bat, so if you want a quick function to work I bashed this together pretty quickly, there are probably more efficent ways of processing this, but it gets the job done. Enjoy.

[code]
<?php

//Note: I ran this in PHP 5.3.x
function NTPtoUnixtime($ntptime)
{
   
$explodedNTPtime = explode(" ", $ntptime,2);
   
$startOfDay = strtotime("Today");
   
$timeThroughDay = strtotime($explodedNTPtime[0]) - $startOfDay ;
    return
strtotime($explodedNTPtime[1])+$timeThroughDay;
}

$ntpTime = "09:49:22.897 NZDT Mon Feb 20 2012"; //NTP time to convert.

echo NTPtoUnixtime($ntpTime);

//produces: 1329684562
// Which equates to: Mon 20 Feb 2012 09:49:22 NZDT GMT+13
?>

[/code]
up
0
hushuilong at gmail dot com
2 years ago
There is a bug when around a month change.
The bug url: https://bugs.php.net/bug.php?id=27793

To work around this ,check the method below :

Pass the timestamp of the first second on the first day in current month to strtotime the second parameter.

<?php
date_default_timezone_set
('Asia/Shanghai');

$first_day_of_month = date('Y-m',time()) . '-01 00:00:01';
$t = strtotime($first_day_of_month);
print_r(array(
           
date('Y-m',$t),
           
date('Y-m',strtotime('- 1 month',$t)),
           
date('Y-m',strtotime('- 2 month',$t)),
));
?>
up
0
ei7024 at wayne dot edu
3 years ago
This is the solution to the problems with date below 1970. Below code help the date to show up in format such as MM/DD/YYYY. It can be tailored to fit any format.

This works if the database stores the dates in "DATE" format.

<?php

$query
= "SELECT emp_fn,emp_ln, emp_dob FROM requests WHERE id=$id;";
$result = mysql_query($query,$DBConn);
$row = mysql_fetch_array($result);

//TESTING BELOW 1970 Date of Birth

$dobcheck = strtotime($row['emp_dob']);

//NOTE: echo $dobcheck on your system to see if you get negative values for date below 1970

if ($dobcheck <= 0)
    {
       
$date = $row['emp_dob'];
       
$date = explode('-', $date);
       
$Y = $date[0];
       
$M = $date[1];
       
$D = $date[2];
       
$dobshow = $M."/".$D."/".$Y;        //echos mm/dd/YYYY format for dates below 1970.
   
} else {
       
$dobshow = date("m/d/Y",strtotime($row['emp_dob']));   
    }

//ENDTESTING

?>
up
0
a dot fruchi at bit-runners dot com
3 years ago
If you want to confront a date stored into mysql as a date field (not a datetime) and a date specified by a literal string, be sure to add "midnight" to the literal string, otherwise they won't match:

<?php
//I.E.: today is 17/02/2011

echo strtotime('2011-01-01'); //1293836400
echo strtotime('first day of last month'); //1293888128 Note: it's different from the previous one, since it computes also the seconds passed from midnight!!! So this one is always greater than simple '2011-01-01'
echo strtotime('midnight first day of last monty');//1293836400 Note: it's the same as '2011-01-01'

?>
up
0
prajo74 at gmail dot com
4 years ago
Take Care: strtotime() may not add months properly. The out put may not be as expected.

<?php echo '<br />'.date("Y-m-d", strtotime('+1 month', mktime(0,0,0,1,31,2010))); ?>

PHP Output - 2010-03-03 (Version 5.3.2) (Not Expected)

MySQL Output while adding 1 month to 2010-01-31 will be 2010-02-28 (As Expeced)
up
0
chris at teamsiems dot com
4 years ago
It took me a while to notice that strtotime starts searching from just after midnight of the first day of the month. So, if the month starts on the day you search for, the first day of the search is actually the next occurrence of the day.

In my case, when I look for first Tuesday of the current month, I need to include a check to see if the month starts on a Tuesday.

<?php
if (date("l", strtotime("$thisMonth $thisYear"))=='Tuesday') {
  echo
"<p>This month starts on a Tuesday. Use \"$thisMonth $thisYear\" to check for first Tuesday.</p>\n";
} else {
  echo
"<p>This month does not start on a Tuesday. Use \"first tuesday $thisMonth $thisYear\" to check for first Tuesday.</p>\n";
}
?>
up
0
Travis Pulley
4 years ago
Be aware that if you are running 5.2.8, there is a memory leak with this function and it could cost someone valuable time finding out what the problem was. Per usual, running the latest (minor) version tends to be a good idea.

See here: http://bugs.php.net/bug.php?id=46889
up
0
Peter
5 years ago
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.
up
0
CEO at CarPool2Camp dot org
5 years ago
Another way to get the last day of a given month is to use date('t');
up
-1
Alex Austin
4 years ago
Seems in PHP5 there are new values that can be passed to the function:

<?php
echo time();
echo
'<br>';
echo
strtotime('noon');
echo
'<br>';
echo
strtotime('midnight');
echo
'<br>';
echo
strtotime('10am');
echo
'<br>';
echo
strtotime('2pm');
?>
up
-2
karim at sweetcode dot co dot uk
4 years ago
A handy function I wrote to tell you whether a given date (unix timestamp) is a working day in the UK. i.e. not a bank holiday or weekend day. Returns true or false.

<?php 
function isUkWorkingDay( $utDate )
  {
   
/* weekend? */
   
if( date( 'N', $utDate ) > 5 ){
      return
false;
    }
   
   
/* bank holiday? */
   
$year = date( 'Y', $utDate );

   
$utFirstJan = strtotime( '1st jan ' . $year );

   
$firstJanDay = date( 'N'$utFirstJan );

    if (
$firstJanDay > 5 ){ // sat or sun
     
$holidays[] = date( 'Y-m-d', strtotime( 'first monday january ' . $year ));
    }
    else{
     
$holidays[] = date( 'Y-m-d'$utFirstJan) ;
    }

   
$utEasterSunday = easter_date( $year );
   
$holidays[] = date( 'Y-m-d', strtotime( 'last friday', $utEasterSunday ));
   
$holidays[] = date( 'Y-m-d', strtotime( 'next monday', $utEasterSunday ));
   
$holidays[] = date( 'Y-m-d', strtotime( 'first monday may ' . $year ));
   
$holidays[] = date( 'Y-m-d', strtotime( 'last monday june ' . $year )); // end of may B.H.
   
$holidays[] = date( 'Y-m-d', strtotime( 'last monday september ' . $year ));  // end of August B.H.

   
$xmasDay = date( strtotime( '25th december ' . $year ) );
    if (
date( 'N', $xmasDay ) == 5 ){ // falls on friday
     
$holidays[] = date( 'Y-m-d', $xmasDay );
     
$holidays[] = date( 'Y-m-d', strtotime( 'next monday', $xmasDay ));
    }
    if (
date( 'N', $xmasDay ) > 5 ){ // falls on sat or sun
     
$holidays[] = date( 'Y-m-d', strtotime( 'next monday', $xmasDay ));
     
$holidays[] = date( 'Y-m-d', strtotime( 'next tuesday', $xmasDay ));
    }
    if (
date( 'N', $xmasDay ) < 5 ){ // falls on mon to thurs
     
$holidays[] = date( 'Y-m-d', $xmasDay );
     
$holidays[] = date( 'Y-m-d', strtotime( 'next day', $xmasDay ));
    }

    return( !
in_array( date( 'Y-m-d', $utDate ), $holidays ) ) ;
  }
?>
up
-3
Beat
6 years ago
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

?>

Here the workaround 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

?>
up
-4
sgutauckis
7 years ago
The following might produce something different than you might expect:
<?php
   
echo date('l, F jS Y', strtotime("third wednesday", strtotime("2006-11-01"))) . "<br>";
    echo
date('l, F jS Y', strtotime("third sunday", strtotime("2006-01-01")));
?>
Produces:
Wednesday, November 22nd 2006
Sunday, January 22nd 2006

The problem stems from strtotime when the requested day falls on the date passed to strtotime. If you look at your calendar you will see that they should return:

Wednesday, November 15th 2006
Sunday, January 15th 2006

Because the date falls on the day requested it skips that day.
up
-6
besluitloos at gmail dot com
2 years ago
I just found out PHP thinks slashes in date-formats aren't very european:
(I guess this is not a bug, just the way it works. But correct me if I'm wrong.)
<?php

    $date
= "06/10/2011 14:28"; // 6 october 2011 2:28 pm
   
$otherDate = "06-10-2011 14:28"; // 6 october 2011 2:28 pm
   
   
echo $stamp = strtotime($date) . "<br />"; // outputs 1307708880
   
echo $otherStamp = strtotime($otherDate) . "<br />"; // outputs 1317904080
   
   
echo date("d-m", $stamp); // outputs 10-06
   
echo date("d-m", $otherStamp); // outputs 06-10

?>
up
-2
les dot mc dot pls at gmail dot com
9 months ago
@lazzich
just wanted to say that by coincidence i commented out the:

//$date(2011/07/15);
//$time(15:00:00);

and the result was 16,000 days ago...

Happy 16,000 day anniversary of
01/01/1970 everyone!!!
up
-5
miamiseb at nospam_gmail dot com
9 years ago
If you strtotime the epoch (Jan 1 1970 00:00:00) you will usually get a value, rather than the expected 0. So for example, if you were to try to use the epoch to calculate the difference in times (strtotime(Jan 1 1970 21:00:00)-strtotime(Jan 1 1970 20:00:00) for example) You get a value that depends strongly upon your timezone. If you are in EST for example, the epoch is actually shifted -5 to YOUR epoch is Jan 1 1970 19:00:00) In order to get the offset, simply use the following call to report the number of seconds you are away from the unix epoch. $offset=strtotime("1970-01-01 00:00:00"); Additionally, you can append GMT at the end of your strtotime calls so save yourself the trouble of converting relative to timezone.
up
-6
octavio
4 years ago
This function calculates if date2 is within an interval of seconds from date1.

<?php
function is_on_interval($date1,$date2,$interval){
   
$dat2=strtotime($date2);
   
$dat3=strtotime('+'.$interval.' second '.$date1);
   
    if(
$dat2>=$dat3){
        return
false;
    }
    else
    {
        return
true;
    }
}

$date1='2009-08-18 00:02:00';
$date2='2009-08-18 00:05:00';
?>

$date2 is 180 seconds from $date1.

<?php is_on_interval($date1,$date2,'120'); ?>
will return false.

<?php is_on_interval($date1,$date2,'180'); ?>
will return true.

<?php is_on_interval($date1,$date2,'220'); ?>
will return true.
up
-6
Leon F.
4 years ago
I needed to generate timestamps for specific days of the week in a month (e.g. the 2nd wednesday or the 3rd friday).  After messing about with different syntax, I found this works pretty consistently:

<?php
strtotime
('+0 week sun nov 2009'); // first sunday in nov 2009
strtotime('+1 week sun nov 2009'); // second sunday
strtotime('-1 week sun nov 2009'); // last sunday in oct 2009
?>

This is helping me considerably in parsing ical spec's RRULE sets for example.
up
-7
shaver at qspeed dot com
8 years ago
I'm posting these here as I believe these to be design changes, not bugs.

For those upgrading from PHP 4 to PHP 5 there are a number of things that are different about strtotime that I have NOT seen documented elsewhere, or at least not as clearly. I confirmed these with two separate fresh installations of PHP 4.4.1 and PHP 5.1.1.

1) Given that today is Tuesday: PHP4 "next tuesday" will return today. PHP5 "next tuesday" will actually return next tuesday as in "today +1week". Note that behavior has NOT changed for "last" and "this". For the string "last tuesday" both PHP4 and PHP5 would return "today -1week".  For the string "this tuesday" both PHP4 and PHP5 would return "today".

2) You cannot include a space immediately following a + or - in PHP 5. In PHP4 the string "today + 1 week" works great. in PHP5 the string must be "today +1 week" to correctly parse.

3) (Partially noted in changelog.) If you pass php4 a string that is a mess ("asdf1234") it will return -1. If you in turn pass this to date() you'll get a warning like: Windows does not support dates prior to midnight. This is pretty useful for catching errors in your scripts. In PHP 5 strtotime will return FALSE which causes date() to return 12/31/69. Note that this is true of strings that might appear right such as "two weeks".

4) (Partially noted in changelog.) If you pass php4 an empty string it will error out with a "Notice: strtotime(): Called with empty time parameter". PHP5 will give no notice and return the current date stamp. (A much preferred behavior IMO.)

5) Some uppercase and mixed-case strings no longer parse correctly. In php4 "Yesterday" would parse correctly. In php5 "Yesterday" will return the infamous 1969 date. This is also true of Tomorrow and Today. [Red. This has been fixed in PHP already]

6. The keyword "previous" is supported in PHP5. (Finally!)

Good luck with your upgrades. :)
-Will
up
-9
clarkDONTSPAMMEwise at gmail dot com
4 years ago
Always use the format strtotime("+1 day") when adding/subtracting units of time rather than manually adding 24*60*60 seconds to a timestamp, for example, as this format works as desired with Daylight Saving Time changes. If your timezone adheres to Daylight Saving Time, a situation like the following may apply to you:

<?php
date_default_timezone_set
('America/Chicago');

// Don't do this:
$today = '2009-11-01';
$tomorrow = strtotime($today) + 24*3600;
print
date('Y-m-d', $tomorrow);
// Output: 2009-11-01

// Do this instead:
$today = '2009-11-01';
$tomorrow = strtotime('+1 day', strtotime($today));
print
date('Y-m-d', $tomorrow);
// Output: 2009-11-02
To Top