#### [SOLVED] How to calculate the difference between two dates using PHP?

By gnanesh

I have two dates of the form:

``````Start Date: 2007-03-24
End Date: 2009-06-26
``````

Now I need to find the difference between these two in the following form:

``````2 years, 3 months and 2 days
``````

How can I do this in PHP?

#### @Emil H 2009-03-24 10:35:11

Use this for legacy code (PHP < 5.3). For up to date solution see jurka's answer below

You can use strtotime() to convert two dates to unix time and then calculate the number of seconds between them. From this it's rather easy to calculate different time periods.

``````\$date1 = "2007-03-24";
\$date2 = "2009-06-26";

\$diff = abs(strtotime(\$date2) - strtotime(\$date1));

\$years = floor(\$diff / (365*60*60*24));
\$months = floor((\$diff - \$years * 365*60*60*24) / (30*60*60*24));
\$days = floor((\$diff - \$years * 365*60*60*24 - \$months*30*60*60*24)/ (60*60*24));

printf("%d years, %d months, %d days\n", \$years, \$months, \$days);
``````

Edit: Obviously the preferred way of doing this is like described by jurka below. My code is generally only recommended if you don't have PHP 5.3 or better.

Several people in the comments have pointed out that the code above is only an approximation. I still believe that for most purposes that's fine, since the usage of a range is more to provide a sense of how much time has passed or remains rather than to provide precision - if you want to do that, just output the date.

Despite all that, I've decided to address the complaints. If you truly need an exact range but haven't got access to PHP 5.3, use the code below (it should work in PHP 4 as well). This is a direct port of the code that PHP uses internally to calculate ranges, with the exception that it doesn't take daylight savings time into account. That means that it's off by an hour at most, but except for that it should be correct.

``````<?php

/**
* Calculate differences between two dates with precise semantics. Based on PHPs DateTime::diff()
* implementation by Derick Rethans. Ported to PHP by Emil H, 2011-05-02. No rights reserved.
*
* See here for original code:
* http://svn.php.net/viewvc/php/php-src/trunk/ext/date/lib/tm2unixtime.c?revision=302890&view=markup
* http://svn.php.net/viewvc/php/php-src/trunk/ext/date/lib/interval.c?revision=298973&view=markup
*/

function _date_range_limit(\$start, \$end, \$adj, \$a, \$b, \$result)
{
if (\$result[\$a] < \$start) {
\$result[\$b] -= intval((\$start - \$result[\$a] - 1) / \$adj) + 1;
\$result[\$a] += \$adj * intval((\$start - \$result[\$a] - 1) / \$adj + 1);
}

if (\$result[\$a] >= \$end) {
}

return \$result;
}

function _date_range_limit_days(\$base, \$result)
{
\$days_in_month_leap = array(31, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
\$days_in_month = array(31, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);

_date_range_limit(1, 13, 12, "m", "y", &\$base);

\$year = \$base["y"];
\$month = \$base["m"];

if (!\$result["invert"]) {
while (\$result["d"] < 0) {
\$month--;
if (\$month < 1) {
\$month += 12;
\$year--;
}

\$leapyear = \$year % 400 == 0 || (\$year % 100 != 0 && \$year % 4 == 0);
\$days = \$leapyear ? \$days_in_month_leap[\$month] : \$days_in_month[\$month];

\$result["d"] += \$days;
\$result["m"]--;
}
} else {
while (\$result["d"] < 0) {
\$leapyear = \$year % 400 == 0 || (\$year % 100 != 0 && \$year % 4 == 0);
\$days = \$leapyear ? \$days_in_month_leap[\$month] : \$days_in_month[\$month];

\$result["d"] += \$days;
\$result["m"]--;

\$month++;
if (\$month > 12) {
\$month -= 12;
\$year++;
}
}
}

return \$result;
}

function _date_normalize(\$base, \$result)
{
\$result = _date_range_limit(0, 60, 60, "s", "i", \$result);
\$result = _date_range_limit(0, 60, 60, "i", "h", \$result);
\$result = _date_range_limit(0, 24, 24, "h", "d", \$result);
\$result = _date_range_limit(0, 12, 12, "m", "y", \$result);

\$result = _date_range_limit_days(&\$base, &\$result);

\$result = _date_range_limit(0, 12, 12, "m", "y", \$result);

return \$result;
}

/**
* Accepts two unix timestamps.
*/
function _date_diff(\$one, \$two)
{
\$invert = false;
if (\$one > \$two) {
list(\$one, \$two) = array(\$two, \$one);
\$invert = true;
}

\$key = array("y", "m", "d", "h", "i", "s");
\$a = array_combine(\$key, array_map("intval", explode(" ", date("Y m d H i s", \$one))));
\$b = array_combine(\$key, array_map("intval", explode(" ", date("Y m d H i s", \$two))));

\$result = array();
\$result["y"] = \$b["y"] - \$a["y"];
\$result["m"] = \$b["m"] - \$a["m"];
\$result["d"] = \$b["d"] - \$a["d"];
\$result["h"] = \$b["h"] - \$a["h"];
\$result["i"] = \$b["i"] - \$a["i"];
\$result["s"] = \$b["s"] - \$a["s"];
\$result["invert"] = \$invert ? 1 : 0;
\$result["days"] = intval(abs((\$one - \$two)/86400));

if (\$invert) {
_date_normalize(&\$a, &\$result);
} else {
_date_normalize(&\$b, &\$result);
}

return \$result;
}

\$date = "1986-11-10 19:37:22";

print_r(_date_diff(strtotime(\$date), time()));
print_r(_date_diff(time(), strtotime(\$date)));
``````

#### @Jon Cram 2009-08-07 13:26:41

If you're using the DateTime class you can go for \$date->format('U') to get the unix timestamp.

#### @Arno 2009-12-21 15:54:04

It's not true if you have to deal with summer/winter time. In this particular case when you adjust summer/winter time, one day equals 23 or 25 hours.

#### @Emil H 2009-12-21 20:35:49

Well, the same argument could be made for leap years. It doesn't take that into account either. Still, I'm not convinced that you even want to take that into account since we're discussing a range here. The semantics for a range are somewhat different than for an absolute date.

#### @enobrev 2011-04-11 19:14:44

This function is incorrect. It's good for an approximation, but incorrect for exact ranges. For one, it assumes there are 30 days in a month, which is to say it will have the same difference of days between February 1st and March 1st as it will for July 1st to August 1st (regardless of leap year).

#### @Paul Tarjan 2013-03-19 09:32:08

In PHP, reference variables are in the function signature, not the call. Move all your `&` to the signatures.

#### @Parixit 2013-10-16 07:11:46

Though this is accepted answer but, if you are using PHP 5.3 or greater than please check the following answer on this question stackoverflow.com/a/3923228/631652

#### @Chris Baker 2014-09-13 00:46:15

Doing math on time is flawed -- use the Date object that is designed to take into account all the possibly variations and exceptions.

#### @larp 2018-12-27 09:41:12

Try this very simple answer using date_diff(), this is tested.

``````\$date1 = date_create("2017-11-27");
\$date2 = date_create("2018-12-29");
\$diff=date_diff(\$date1,\$date2);
\$months = \$diff->format("%m months");
\$years = \$diff->format("%y years");
\$days = \$diff->format("%d days");

echo \$years .' '.\$months.' '.\$days;
``````

the output is:

``````1 years 1 months 2 days
``````

#### @Mosin 2017-12-15 11:54:08

Here is the runnable code

``````\$date1 = date_create('2007-03-24');
\$date2 = date_create('2009-06-26');
\$diff1 = date_diff(\$date1,\$date2);
\$daysdiff = \$diff1->format("%R%a");
\$daysdiff = abs(\$daysdiff);
``````

#### @Anuj 2012-12-09 11:14:23

An easy function

``````function time_difference(\$time_1, \$time_2, \$limit = null)
{

\$val_1 = new DateTime(\$time_1);
\$val_2 = new DateTime(\$time_2);

\$interval = \$val_1->diff(\$val_2);

\$output = array(
"year" => \$interval->y,
"month" => \$interval->m,
"day" => \$interval->d,
"hour" => \$interval->h,
"minute" => \$interval->i,
"second" => \$interval->s
);

\$return = "";
foreach (\$output AS \$key => \$value) {

if (\$value == 1)
\$return .= \$value . " " . \$key . " ";
elseif (\$value >= 1)
\$return .= \$value . " " . \$key . "s ";

if (\$key == \$limit)
return trim(\$return);
}
return trim(\$return);
}
``````

Use like

`echo time_difference (\$time_1, \$time_2, "day");`

Will return like `2 years 8 months 2 days`

I would prefer to use `date_create` and `date_diff` objects.

Code:

``````\$date1 = date_create("2007-03-24");
\$date2 = date_create("2009-06-26");

\$dateDifference = date_diff(\$date1, \$date2)->format('%y years, %m months and %d days');

echo \$dateDifference;
``````

Output:

``````2 years, 3 months and 2 days
``````

For more info read PHP `date_diff` manual

According to manual `date_diff` is an alias of DateTime::diff()

#### @Abhijit 2017-10-04 06:55:48

``````\$date = '2012.11.13';
\$dateOfReturn = '2017.10.31';

\$substract = str_replace('.', '-', \$date);

\$substract2 = str_replace('.', '-', \$dateOfReturn);

\$date1 = \$substract;
\$date2 = \$substract2;

\$ts1 = strtotime(\$date1);
\$ts2 = strtotime(\$date2);

\$year1 = date('Y', \$ts1);
\$year2 = date('Y', \$ts2);

\$month1 = date('m', \$ts1);
\$month2 = date('m', \$ts2);

echo \$diff = ((\$year2 - \$year1) * 12) + (\$month2 - \$month1);
``````

#### @bikram kc 2017-06-07 04:58:31

For php version >=5.3 : Create two date objects and then use `date_diff()` function. It will return php DateInterval object. see documentation

``````\$date1=date_create("2007-03-24");
\$date2=date_create("2009-06-26");
\$diff=date_diff(\$date1,\$date2);
echo \$diff->format("%R%a days");
``````

#### @Rickus Harmse 2016-05-24 09:38:03

you can always use the following function that can return the age in years and months (ie. 1 Year 4 Months)

``````function getAge(\$dob, \$age_at_date)
{
\$d1 = new DateTime(\$dob);
\$d2 = new DateTime(\$age_at_date);
\$age = \$d2->diff(\$d1);
\$years = \$age->y;
\$months = \$age->m;

return \$years.'.'.months;
}
``````

or if you want the age to be calculated at the current date, you can use

``````function getAge(\$dob)
{
\$d1 = new DateTime(\$dob);
\$d2 = new DateTime(date());
\$age = \$d2->diff(\$d1);
\$years = \$age->y;
\$months = \$age->m;

return \$years.'.'.months;
}
``````

#### @jurka 2010-10-13 11:43:23

I suggest to use DateTime and DateInterval objects.

``````\$date1 = new DateTime("2007-03-24");
\$date2 = new DateTime("2009-06-26");
\$interval = \$date1->diff(\$date2);
echo "difference " . \$interval->y . " years, " . \$interval->m." months, ".\$interval->d." days ";

// shows the total amount of days (not divided into years, months and days like above)
echo "difference " . \$interval->days . " days ";
``````

From the manual:

As of PHP 5.2.2, DateTime objects can be compared using comparison operators.

``````\$date1 = new DateTime("now");
\$date2 = new DateTime("tomorrow");

var_dump(\$date1 == \$date2); // bool(false)
var_dump(\$date1 < \$date2);  // bool(true)
var_dump(\$date1 > \$date2);  // bool(false)
``````

#### @cerberos 2011-04-01 08:58:22

note that DateTime->diff() is php 5.3+

#### @hakre 2011-08-07 12:03:03

+1 DateTime handles leap years and time-zones properly and there's a good book for the shelf: phparch.com/books/…

#### @feeela 2012-02-09 13:32:21

note that PHP 5.3 is out since 2009

#### @potatoe 2012-02-19 03:52:27

Is there a method that gives the total number of seconds between the two DateTimes? (without adding up the components, that is)

#### @Sliq 2012-06-27 11:45:04

correct me if i'm wrong but i think it needs to be `\$interval->days` instead of `\$interval->d` !?!?!?

#### @jurka 2012-07-18 12:20:39

@Panique The \$interval->days and \$interval->d are different measures. your comment above is right "shows the total amount of days (not divided into years, months and days like above)"

#### @Paulo Freitas 2012-08-04 21:17:51

@potatoe You probably want `\$date2->format('U') - \$date1->format('U')`.

#### @Pim Schaaf 2013-03-16 09:26:24

note that there's a bug where DateInterval has an incorrect days property (always 6015) on Windows with some PHP versions: bugs.php.net/bug.php?id=51184 (refer to comments there for fix/workaround)

#### @Alejandro Moreno 2013-08-23 12:48:50

what if Date2 is previous to Date1?

#### @Glavić 2013-08-23 13:03:10

@AlejandroMoreno : then `\$interval->invert` will be `1`. Why don't you just try it and `print_r(\$interval)` and you will see all the properties.

#### @Chinmay Sarupria 2016-02-08 12:06:24

It only returns positive values. How to get negative values only?

#### @Muneem Habib 2016-04-21 07:18:17

but it doesnot compare hours and minutes

@ChinmaySarupria \$interval->invert tells you the "direction" `\$diff = \$now->diff(\$future); // \$diff->invert = 0` where `\$diff = \$now->diff(\$past); // \$diff->invert = 1`

#### @KristCont 2017-02-02 08:12:48

When I tried to `var_dump` the `\$interval` it gives me many options to select the intervals from `y,m,d,h,i,s'.. isn't great? thanks!

#### @Constantin Galbenu 2017-03-15 06:34:54

Although it does not change the outcome, I recommend the use of `\DateTimeImmutable` instead of `DateTime` , as, in this case, the two values are value objects (in DDD terms).

#### @Choudhury Saadmaan Mahmid 2014-09-30 05:28:18

Very simple:

``````    <?php
\$date1 = date_create("2007-03-24");
echo "Start date: ".\$date1->format("Y-m-d")."<br>";
\$date2 = date_create("2009-06-26");
echo "End date: ".\$date2->format("Y-m-d")."<br>";
\$diff = date_diff(\$date1,\$date2);
echo "Difference between start date and end date: ".\$diff->format("%y years, %m months and %d days")."<br>";
?>
``````

PHP: date_diff - Manual

Note that it's for PHP 5.3.0 or greater.

#### @Hardik Raval 2011-12-13 06:58:55

I have some simple logic for that:

``````<?php
per_days_diff('2011-12-12','2011-12-29')
function per_days_diff(\$start_date, \$end_date) {
\$per_days = 0;
\$noOfWeek = 0;
\$noOfWeekEnd = 0;
\$highSeason=array("7", "8");

\$current_date = strtotime(\$start_date);
\$current_date += (24 * 3600);
\$end_date = strtotime(\$end_date);

\$seassion = (in_array(date('m', \$current_date), \$highSeason))?"2":"1";

\$noOfdays = array('');

while (\$current_date <= \$end_date) {
if (\$current_date <= \$end_date) {
\$date = date('N', \$current_date);
array_push(\$noOfdays,\$date);
\$current_date = strtotime('+1 day', \$current_date);
}
}

\$finalDays = array_shift(\$noOfdays);
//print_r(\$noOfdays);
\$weekFirst = array("week"=>array(),"weekEnd"=>array());
for(\$i = 0; \$i < count(\$noOfdays); \$i++)
{
if (\$noOfdays[\$i] == 1)
{
//echo "This is week";
//echo "<br/>";
if(\$noOfdays[\$i+6]==7)
{
\$noOfWeek++;
\$i=\$i+6;
}
else
{
\$per_days++;
}
//array_push(\$weekFirst["week"],\$day);
}
else if(\$noOfdays[\$i]==5)
{
//echo "This is weekend";
//echo "<br/>";
if(\$noOfdays[\$i+2] ==7)
{
\$noOfWeekEnd++;
\$i = \$i+2;
}
else
{
\$per_days++;
}
//echo "After weekend value:- ".\$i;
//echo "<br/>";
}
else
{
\$per_days++;
}
}

/*echo \$noOfWeek;
echo "<br/>";
echo \$noOfWeekEnd;
echo "<br/>";
print_r(\$per_days);
echo "<br/>";
print_r(\$weekFirst);
*/

\$duration = array("weeks"=>\$noOfWeek, "weekends"=>\$noOfWeekEnd, "perDay"=>\$per_days, "seassion"=>\$seassion);
return \$duration;
?>
``````

#### @Peter Mortensen 2014-04-08 23:52:46

There seems to be something missing at the end of the sample code (an ending brace and "?>" ?).

"simple" logic. These are at least 40 lines of pure code.

#### @Champ 2012-09-20 14:09:28

Some time ago I wrote a `format_date` function as this gives many options on how you want your date:

``````function format_date(\$date, \$type, \$seperator="-")
{
if(\$date)
{
\$day = date("j", strtotime(\$date));
\$month = date("n", strtotime(\$date));
\$year = date("Y", strtotime(\$date));
\$hour = date("H", strtotime(\$date));
\$min = date("i", strtotime(\$date));
\$sec = date("s", strtotime(\$date));

switch(\$type)
{
case 0:  \$date = date("Y".\$seperator."m".\$seperator."d",mktime(\$hour, \$min, \$sec, \$month, \$day, \$year)); break;
case 1:  \$date = date("D, F j, Y",mktime(\$hour, \$min, \$sec, \$month, \$day, \$year)); break;
case 2:  \$date = date("d".\$seperator."m".\$seperator."Y",mktime(\$hour, \$min, \$sec, \$month, \$day, \$year)); break;
case 3:  \$date = date("d".\$seperator."M".\$seperator."Y",mktime(\$hour, \$min, \$sec, \$month, \$day, \$year)); break;
case 4:  \$date = date("d".\$seperator."M".\$seperator."Y h:i A",mktime(\$hour, \$min, \$sec, \$month, \$day, \$year)); break;
case 5:  \$date = date("m".\$seperator."d".\$seperator."Y",mktime(\$hour, \$min, \$sec, \$month, \$day, \$year)); break;
case 6:  \$date = date("M",mktime(\$hour, \$min, \$sec, \$month, \$day, \$year)); break;
case 7:  \$date = date("Y",mktime(\$hour, \$min, \$sec, \$month, \$day, \$year)); break;
case 8:  \$date = date("j",mktime(\$hour, \$min, \$sec, \$month, \$day, \$year)); break;
case 9:  \$date = date("n",mktime(\$hour, \$min, \$sec, \$month, \$day, \$year)); break;
case 10:
\$diff = abs(strtotime(\$date) - strtotime(date("Y-m-d h:i:s")));
\$years = floor(\$diff / (365*60*60*24));
\$months = floor((\$diff - \$years * 365*60*60*24) / (30*60*60*24));
\$days = floor((\$diff - \$years * 365*60*60*24 - \$months*30*60*60*24)/ (60*60*24));
\$date = \$years . " years, " . \$months . " months, " . \$days . "days";
}
}
return(\$date);
}
``````

#### @Peter Mortensen 2014-04-09 00:00:42

This answer is just as wrong as khaldonno's answer. It assumes (case 10) that a year has 365 days (every fourth year has 366 days (except for the 100 year / 400 years rules for the Gregorian calendar)), and that a month has 30 days (it is about approximately 30.42 days in non-leap years). Even with better constants it is only correct on average, not necessarily correct for any two particular dates.

#### @casper123 2011-07-25 14:37:05

Take a look at the following link. This is the best answer I've found so far.. :)

``````function dateDiff (\$d1, \$d2) {

// Return the number of days between the two dates:
return round(abs(strtotime(\$d1) - strtotime(\$d2))/86400);

} // end function dateDiff
``````

It doesn't matter which date is earlier or later when you pass in the date parameters. The function uses the PHP ABS() absolute value to always return a postive number as the number of days between the two dates.

Keep in mind that the number of days between the two dates is NOT inclusive of both dates. So if you are looking for the number of days represented by all the dates between and including the dates entered, you will need to add one (1) to the result of this function.

For example, the difference (as returned by the above function) between 2013-02-09 and 2013-02-14 is 5. But the number of days or dates represented by the date range 2013-02-09 - 2013-02-14 is 6.

http://www.bizinfosys.com/php/date-difference.html

#### @Peter Mortensen 2014-04-08 23:41:57

The question asked for the difference as the number of years, months and days, not the total number of days.

#### @vengat 2011-02-17 18:29:55

``````<?php
\$today = strtotime("2011-02-03 00:00:00");
\$myBirthDate = strtotime("1964-10-30 00:00:00");
printf("Days since my birthday: ", (\$today - \$myBirthDate)/60/60/24);
?>
``````

#### @Peter Mortensen 2014-04-08 23:40:23

The question asked for the difference as the number of years, months and days. This outputs the difference as the total number of days.

#### @James - Php Development 2010-01-07 02:22:34

I found your article on the following page, which contains a number of references for PHP date time calculations.

Calculate the difference between two Dates (and time) using PHP. The following page provides a range of different methods (7 in total) for performing date / time calculations using PHP, to determine the difference in time (hours, munites), days, months or years between two dates.

#### @ElasticThoughts 2014-03-31 03:02:40

"if" the date is stored in MySQL, I find it easier to do the difference calculation at the database level... Then based on the Day, Hour, Min, Sec output, parse and display results as appropriate...

``````mysql> select firstName, convert_tz(loginDate, '+00:00', '-04:00') as loginDate, TIMESTAMPDIFF(DAY, loginDate, now()) as 'Day', TIMESTAMPDIFF(HOUR, loginDate, now())+4 as 'Hour', TIMESTAMPDIFF(MINUTE, loginDate, now())+(60*4) as 'Min', TIMESTAMPDIFF(SECOND, loginDate, now())+(60*60*4) as 'Sec' from User_ where userId != '10158' AND userId != '10198' group by emailAddress order by loginDate desc;
+-----------+---------------------+------+------+------+--------+
| firstName | loginDate           | Day  | Hour | Min  | Sec    |
+-----------+---------------------+------+------+------+--------+
| Peter     | 2014-03-30 18:54:40 |    0 |    4 |  244 |  14644 |
| Keith     | 2014-03-30 18:54:11 |    0 |    4 |  244 |  14673 |
| Andres    | 2014-03-28 09:20:10 |    2 |   61 | 3698 | 221914 |
| Nadeem    | 2014-03-26 09:33:43 |    4 |  109 | 6565 | 393901 |
+-----------+---------------------+------+------+------+--------+
4 rows in set (0.00 sec)
``````

#### @ChrisV 2014-01-19 17:25:58

Since everyone is posting code samples, here is another version.

I wanted a function to display differences from seconds to years (just one unit). For periods over 1 day, I wanted it to rollover at midnight (10am Monday seen from 9am Wednesday is 2 days ago, not 1). And for periods over a month, I wanted the rollover to be on the same day of the month (including for 30/31 day months & leap years).

This is what I came up with:

``````/**
* Returns how long ago something happened in the past, showing it
* as n seconds / minutes / hours / days / weeks / months / years ago.
*
* For periods over a day, it rolls over at midnight (so doesn't depend
* on current time of day), and it correctly accounts for month-lengths
* and leap-years (months and years rollover on current day of month).
*
* \$param string \$timestamp in DateTime format
* \$return string description of interval
*/
function ago(\$timestamp)
{
\$then = date_create(\$timestamp);

// for anything over 1 day, make it rollover on midnight
\$today = date_create('tomorrow'); // ie end of today
\$diff = date_diff(\$then, \$today);

if (\$diff->y > 0) return \$diff->y.' year'.(\$diff->y>1?'s':'').' ago';
if (\$diff->m > 0) return \$diff->m.' month'.(\$diff->m>1?'s':'').' ago';
\$diffW = floor(\$diff->d / 7);
if (\$diffW > 0) return \$diffW.' week'.(\$diffW>1?'s':'').' ago';
if (\$diff->d > 1) return \$diff->d.' day'.(\$diff->d>1?'s':'').' ago';

// for anything less than 1 day, base it off 'now'
\$now = date_create();
\$diff = date_diff(\$then, \$now);

if (\$diff->d > 0) return 'yesterday';
if (\$diff->h > 0) return \$diff->h.' hour'.(\$diff->h>1?'s':'').' ago';
if (\$diff->i > 0) return \$diff->i.' minute'.(\$diff->i>1?'s':'').' ago';
return \$diff->s.' second'.(\$diff->s==1?'':'s').' ago';
}
``````

#### @techouse 2013-11-14 12:55:26

I had the same problem with PHP 5.2 and solved it with MySQL. Might not be exactly what you're looking for, but this will do the trick and return the number of days:

``````\$datediff_q = \$dbh->prepare("SELECT DATEDIFF(:date2, :date1)");
\$datediff_q->bindValue(':date1', '2007-03-24', PDO::PARAM_STR);
\$datediff_q->bindValue(':date2', '2009-06-26', PDO::PARAM_STR);
\$datediff = (\$datediff_q->execute()) ? \$datediff_q->fetchColumn(0) : false;
``````

#### @jerdiggity 2013-11-02 23:48:57

This will try to detect whether a timestamp was given or not, and will also return future dates/times as negative values:

``````<?php

function time_diff(\$start, \$end = NULL, \$convert_to_timestamp = FALSE) {
// If \$convert_to_timestamp is not explicitly set to TRUE,
// check to see if it was accidental:
if (\$convert_to_timestamp || !is_numeric(\$start)) {
// If \$convert_to_timestamp is TRUE, convert to timestamp:
\$timestamp_start = strtotime(\$start);
}
else {
// Otherwise, leave it as a timestamp:
\$timestamp_start = \$start;
}
// Same as above, but make sure \$end has actually been overridden with a non-null,
// non-empty, non-numeric value:
if (!is_null(\$end) && (!empty(\$end) && !is_numeric(\$end))) {
\$timestamp_end = strtotime(\$end);
}
else {
// If \$end is NULL or empty and non-numeric value, assume the end time desired
// is the current time (useful for age, etc):
\$timestamp_end = time();
}
// Regardless, set the start and end times to an integer:
\$start_time = (int) \$timestamp_start;
\$end_time = (int) \$timestamp_end;

// Assign these values as the params for \$then and \$now:
\$start_time_var = 'start_time';
\$end_time_var = 'end_time';
// Use this to determine if the output is positive (time passed) or negative (future):
\$pos_neg = 1;

// If the end time is at a later time than the start time, do the opposite:
if (\$end_time <= \$start_time) {
\$start_time_var = 'end_time';
\$end_time_var = 'start_time';
\$pos_neg = -1;
}

// Convert everything to the proper format, and do some math:
\$then = new DateTime(date('Y-m-d H:i:s', \$\$start_time_var));
\$now = new DateTime(date('Y-m-d H:i:s', \$\$end_time_var));

\$years_then = \$then->format('Y');
\$years_now = \$now->format('Y');
\$years = \$years_now - \$years_then;

\$months_then = \$then->format('m');
\$months_now = \$now->format('m');
\$months = \$months_now - \$months_then;

\$days_then = \$then->format('d');
\$days_now = \$now->format('d');
\$days = \$days_now - \$days_then;

\$hours_then = \$then->format('H');
\$hours_now = \$now->format('H');
\$hours = \$hours_now - \$hours_then;

\$minutes_then = \$then->format('i');
\$minutes_now = \$now->format('i');
\$minutes = \$minutes_now - \$minutes_then;

\$seconds_then = \$then->format('s');
\$seconds_now = \$now->format('s');
\$seconds = \$seconds_now - \$seconds_then;

if (\$seconds < 0) {
\$minutes -= 1;
\$seconds += 60;
}
if (\$minutes < 0) {
\$hours -= 1;
\$minutes += 60;
}
if (\$hours < 0) {
\$days -= 1;
\$hours += 24;
}
\$months_last = \$months_now - 1;
if (\$months_now == 1) {
\$years_now -= 1;
\$months_last = 12;
}

// "Thirty days hath September, April, June, and November" ;)
if (\$months_last == 9 || \$months_last == 4 || \$months_last == 6 || \$months_last == 11) {
\$days_last_month = 30;
}
else if (\$months_last == 2) {
// Factor in leap years:
if ((\$years_now % 4) == 0) {
\$days_last_month = 29;
}
else {
\$days_last_month = 28;
}
}
else {
\$days_last_month = 31;
}
if (\$days < 0) {
\$months -= 1;
\$days += \$days_last_month;
}
if (\$months < 0) {
\$years -= 1;
\$months += 12;
}

// Finally, multiply each value by either 1 (in which case it will stay the same),
// or by -1 (in which case it will become negative, for future dates).
// Note: 0 * 1 == 0 * -1 == 0
\$out = new stdClass;
\$out->years = (int) \$years * \$pos_neg;
\$out->months = (int) \$months * \$pos_neg;
\$out->days = (int) \$days * \$pos_neg;
\$out->hours = (int) \$hours * \$pos_neg;
\$out->minutes = (int) \$minutes * \$pos_neg;
\$out->seconds = (int) \$seconds * \$pos_neg;
return \$out;
}
``````

Example usage:

``````<?php
\$birthday = 'June 2, 1971';
\$check_age_for_this_date = 'June 3, 1999 8:53pm';
\$age = time_diff(\$birthday, \$check_age_for_this_date)->years;
print \$age;// 28
``````

Or:

``````<?php
\$christmas_2020 = 'December 25, 2020';
\$countdown = time_diff(\$christmas_2020);
print_r(\$countdown);
``````

### Use example :

``````echo time_diff_string('2013-05-01 00:22:35', 'now');
echo time_diff_string('2013-05-01 00:22:35', 'now', true);
``````

### Output :

``````4 months ago
4 months, 2 weeks, 3 days, 1 hour, 49 minutes, 15 seconds ago
``````

### Function :

``````function time_diff_string(\$from, \$to, \$full = false) {
\$from = new DateTime(\$from);
\$to = new DateTime(\$to);
\$diff = \$to->diff(\$from);

\$diff->w = floor(\$diff->d / 7);
\$diff->d -= \$diff->w * 7;

\$string = array(
'y' => 'year',
'm' => 'month',
'w' => 'week',
'd' => 'day',
'h' => 'hour',
'i' => 'minute',
's' => 'second',
);
foreach (\$string as \$k => &\$v) {
if (\$diff->\$k) {
\$v = \$diff->\$k . ' ' . \$v . (\$diff->\$k > 1 ? 's' : '');
} else {
unset(\$string[\$k]);
}
}

if (!\$full) \$string = array_slice(\$string, 0, 1);
return \$string ? implode(', ', \$string) . ' ago' : 'just now';
}
``````

#### @Ofir Attia 2014-02-19 10:07:35

if I want to determine if the difference is bigger then 30 minute, what should I do?

#### @Glavić 2014-02-19 10:50:03

@OfirAttia: you have a bunch of questions like that here on SO, just use search. Simple demo

#### @David Bélanger 2013-08-08 19:10:17

This is my function. Required PHP >= 5.3.4. It use DateTime class. Very fast, quick and can do the difference between two dates or even the so called "time since".

``````if(function_exists('grk_Datetime_Since') === FALSE){
function grk_Datetime_Since(\$From, \$To='', \$Prefix='', \$Suffix=' ago', \$Words=array()){
#   Est-ce qu'on calcul jusqu'à un moment précis ? Probablement pas, on utilise maintenant
if(empty(\$To) === TRUE){
\$To = time();
}

#   On va s'assurer que \$From est numérique
if(is_int(\$From) === FALSE){
\$From = strtotime(\$From);
};

#   On va s'assurer que \$To est numérique
if(is_int(\$To) === FALSE){
\$To = strtotime(\$To);
}

#   On a une erreur ?
if(\$From === FALSE OR \$From === -1 OR \$To === FALSE OR \$To === -1){
return FALSE;
}

#   On va créer deux objets de date
\$From = new DateTime(@date('Y-m-d H:i:s', \$From), new DateTimeZone('GMT'));
\$To   = new DateTime(@date('Y-m-d H:i:s', \$To), new DateTimeZone('GMT'));

#   On va calculer la différence entre \$From et \$To
if((\$Diff = \$From->diff(\$To)) === FALSE){
return FALSE;
}

#   On va merger le tableau des noms (par défaut, anglais)
\$Words = array_merge(array(
'year'      => 'year',
'years'     => 'years',
'month'     => 'month',
'months'    => 'months',
'week'      => 'week',
'weeks'     => 'weeks',
'day'       => 'day',
'days'      => 'days',
'hour'      => 'hour',
'hours'     => 'hours',
'minute'    => 'minute',
'minutes'   => 'minutes',
'second'    => 'second',
'seconds'   => 'seconds'
), \$Words);

#   On va créer la chaîne maintenant
if(\$Diff->y > 1){
\$Text = \$Diff->y.' '.\$Words['years'];
} elseif(\$Diff->y == 1){
\$Text = '1 '.\$Words['year'];
} elseif(\$Diff->m > 1){
\$Text = \$Diff->m.' '.\$Words['months'];
} elseif(\$Diff->m == 1){
\$Text = '1 '.\$Words['month'];
} elseif(\$Diff->d > 7){
\$Text = ceil(\$Diff->d/7).' '.\$Words['weeks'];
} elseif(\$Diff->d == 7){
\$Text = '1 '.\$Words['week'];
} elseif(\$Diff->d > 1){
\$Text = \$Diff->d.' '.\$Words['days'];
} elseif(\$Diff->d == 1){
\$Text = '1 '.\$Words['day'];
} elseif(\$Diff->h > 1){
\$Text = \$Diff->h.' '.\$Words['hours'];
} elseif(\$Diff->h == 1){
\$Text = '1 '.\$Words['hour'];
} elseif(\$Diff->i > 1){
\$Text = \$Diff->i.' '.\$Words['minutes'];
} elseif(\$Diff->i == 1){
\$Text = '1 '.\$Words['minute'];
} elseif(\$Diff->s > 1){
\$Text = \$Diff->s.' '.\$Words['seconds'];
} else {
\$Text = '1 '.\$Words['second'];
}

return \$Prefix.\$Text.\$Suffix;
}
}
``````

#### @liza 2013-06-17 15:44:25

``````\$date1 = date_create('2007-03-24');
\$date2 = date_create('2009-06-26');
\$interval = date_diff(\$date1, \$date2);
echo "difference : " . \$interval->y . " years, " . \$interval->m." months, ".\$interval->d." days ";
``````

#### @user2169219 2013-06-12 12:56:27

In for a penny, in for a pound: I have just reviewed several solutions, all providing a complex solution using floor() that then rounds up to a 26 years 12 month and 2 days solution, for what should have been 25 years, 11 months and 20 days!!!!

here is my version of this problem: may not be elegant, may not be well coded, but provides a more closer proximity to a answer if you do not count LEAP years, obviously leap years could be coded into this, but in this case - as someone else said, perhaps you could provide this answer:: I have included all TEST conditions and print_r so that you can see more clearly the construct of the results:: here goes,

// set your input dates/ variables::

``````\$ISOstartDate   = "1987-06-22";
\$ISOtodaysDate = "2013-06-22";
``````

// We need to EXPLODE the ISO yyyy-mm-dd format into yyyy mm dd, as follows::

\$yDate[ ] = explode('-', \$ISOstartDate); print_r (\$yDate);

\$zDate[ ] = explode('-', \$ISOtodaysDate); print_r (\$zDate);

``````// Lets Sort of the Years!
// Lets Sort out the difference in YEARS between startDate and todaysDate ::
\$years = \$zDate[0][0] - \$yDate[0][0];

// We need to collaborate if the month = month = 0, is before or after the Years Anniversary ie 11 months 22 days or 0 months 10 days...
if (\$months == 0 and \$zDate[0][1] > \$ydate[0][1]) {
\$years = \$years -1;
}
// TEST result
echo "\nCurrent years => ".\$years;

// Lets Sort out the difference in MONTHS between startDate and todaysDate ::
\$months = \$zDate[0][1] - \$yDate[0][1];

// TEST result
echo "\nCurrent months => ".\$months;

// Now how many DAYS has there been - this assumes that there is NO LEAP years, so the calculation is APPROXIMATE not 100%
// Lets cross reference the startDates Month = how many days are there in each month IF m-m = 0 which is a years anniversary
// We will use a switch to check the number of days between each month so we can calculate days before and after the years anniversary

switch (\$yDate[0][1]){
case 01:    \$monthDays = '31';  break;  // Jan
case 02:    \$monthDays = '28';  break;  // Feb
case 03:    \$monthDays = '31';  break;  // Mar
case 04:    \$monthDays = '30';  break;  // Apr
case 05:    \$monthDays = '31';  break;  // May
case 06:    \$monthDays = '30';  break;  // Jun
case 07:    \$monthDays = '31';  break;  // Jul
case 08:    \$monthDays = '31';  break;  // Aug
case 09:    \$monthDays = '30';  break;  // Sept
case 10:    \$monthDays = '31';  break;  // Oct
case 11:    \$monthDays = '30';  break;  // Nov
case 12:    \$monthDays = '31';  break;  // Dec
};
// TEST return
echo "\nDays in start month ".\$yDate[0][1]." => ".\$monthDays;

// Lets correct the problem with 0 Months - is it 11 months + days, or 0 months +days???

\$days = \$zDate[0][2] - \$yDate[0][2] +\$monthDays;
echo "\nCurrent days => ".\$days."\n";

// Lets now Correct the months to being either 11 or 0 Months, depending upon being + or - the years Anniversary date
// At the same time build in error correction for Anniversary dates not being 1yr 0m 31d... see if (\$days == \$monthDays )
if(\$days < \$monthDays && \$months == 0)
{
\$months = 11;       // If Before the years anniversary date
}
else    {
\$months = 0;        // If After the years anniversary date
\$years = \$years+1;  // Add +1 to year
\$days = \$days-\$monthDays;   // Need to correct days to how many days after anniversary date
};
// Day correction for Anniversary dates
if (\$days == \$monthDays )   // if todays date = the Anniversary DATE! set days to ZERO
{
\$days = 0;          // days set toZERO so 1 years 0 months 0 days
};

echo "\nTherefore, the number of years/ months/ days/ \nbetween start and todays date::\n\n";

printf("%d years, %d months, %d days\n", \$years, \$months, \$days);
``````

the end result is:: 26 years, 0 months, 0 days

That's how long I have been in business for on the 22nd June 2013 - Ouch!

You can also use following code to return date diff by round fractions up \$date1 = \$duedate; // assign due date echo \$date2 = date("Y-m-d"); // current date \$ts1 = strtotime(\$date1); \$ts2 = strtotime(\$date2); \$seconds_diff = \$ts1 - \$ts2; echo \$datediff = ceil((\$seconds_diff/3600)/24); // return in days

If you use floor method of php instead of ceil it will return you the round fraction down. Please check the difference here, some times if your staging servers timezone is different then the live site time zone in that case you may get different results so change the conditions accordingly.

The best course of action is using PHP's `DateTime` (and `DateInterval`) objects. Each date is encapsulated in a `DateTime` object, and then a difference between the two can be made:

``````\$first_date = new DateTime("2012-11-30 17:03:30");
\$second_date = new DateTime("2012-12-21 00:00:00");
``````

The `DateTime` object will accept any format `strtotime()` would. If an even more specific date format is needed, `DateTime::createFromFormat()` can be used to create the `DateTime` object.

After both objects were instantiated, you substract one from the other with `DateTime::diff()`.

``````\$difference = \$first_date->diff(\$second_date);
``````

`\$difference` now holds a `DateInterval` object with the difference information. A `var_dump()` looks like this:

``````object(DateInterval)
public 'y' => int 0
public 'm' => int 0
public 'd' => int 20
public 'h' => int 6
public 'i' => int 56
public 's' => int 30
public 'invert' => int 0
public 'days' => int 20
``````

To format the `DateInterval` object, we'll need check each value and exclude it if it's 0:

``````/**
* Format an interval to show all existing components.
* If the interval doesn't have a time component (years, months, etc)
* That component won't be displayed.
*
* @param DateInterval \$interval The interval
*
* @return string Formatted interval string.
*/
function format_interval(DateInterval \$interval) {
\$result = "";
if (\$interval->y) { \$result .= \$interval->format("%y years "); }
if (\$interval->m) { \$result .= \$interval->format("%m months "); }
if (\$interval->d) { \$result .= \$interval->format("%d days "); }
if (\$interval->h) { \$result .= \$interval->format("%h hours "); }
if (\$interval->i) { \$result .= \$interval->format("%i minutes "); }
if (\$interval->s) { \$result .= \$interval->format("%s seconds "); }

return \$result;
}
``````

All that's left now is to call our function on the `\$difference` `DateInterval` object:

``````echo format_interval(\$difference);
``````

And we get the correct result:

20 days 6 hours 56 minutes 30 seconds

The complete code used to achieve the goal:

``````/**
* Format an interval to show all existing components.
* If the interval doesn't have a time component (years, months, etc)
* That component won't be displayed.
*
* @param DateInterval \$interval The interval
*
* @return string Formatted interval string.
*/
function format_interval(DateInterval \$interval) {
\$result = "";
if (\$interval->y) { \$result .= \$interval->format("%y years "); }
if (\$interval->m) { \$result .= \$interval->format("%m months "); }
if (\$interval->d) { \$result .= \$interval->format("%d days "); }
if (\$interval->h) { \$result .= \$interval->format("%h hours "); }
if (\$interval->i) { \$result .= \$interval->format("%i minutes "); }
if (\$interval->s) { \$result .= \$interval->format("%s seconds "); }

return \$result;
}

\$first_date = new DateTime("2012-11-30 17:03:30");
\$second_date = new DateTime("2012-12-21 00:00:00");

\$difference = \$first_date->diff(\$second_date);

echo format_interval(\$difference);
``````

#### @Sagar G. 2013-07-22 16:15:29

DateTime() not working on my php server

`DateTime()` is not a function, it's an object, and it's there since PHP 5.2. Make sure that your server supports it.

#### @PhoneixS 2014-07-07 09:21:51

@SecondRikudo DateTime::Diff need PHP 5.3.0

#### @EgoistDeveloper 2017-09-22 08:49:13

We have a problem, exchange first_date to second_date and we're getting same result? Why not say 0 days 0 hours 0 minutes 0 seconds or only 0. Example: 2012-11-30 17:03:30 - 2012-12-21 00:00:00 and 2012-12-21 00:00:00 - 2012-11-30 17:03:30 get same result.

Because diff gives you the difference between the two times. The difference is not 0 regardless of which date comes later.

#### @nickhar 2019-01-03 23:12:28

This is a really good answer as it provides a clear function that can be called from anywhere in a codebase without lots of time calcs. Others answers allow you to drop echoed calcs on the fly that address the symptoms rather than solve the problem... The only element I've added (and pretty much all other posts don't cover this) is the pluralisation of \$interval elements if more than 1.

#### @Alix Axel 2012-11-04 00:15:39

`DateInterval` is great but it has a couple of caveats:

1. only for PHP 5.3+ (but that's really not a good excuse anymore)
2. only supports years, months, days, hours, minutes and seconds (no weeks)
3. it calculates the difference with all of the above + days (you can't get the difference in months only)

To overcome that, I coded the following (improved from @enobrev answer):

``````function date_dif(\$since, \$until, \$keys = 'year|month|week|day|hour|minute|second')
{
\$date = array_map('strtotime', array(\$since, \$until));

if ((count(\$date = array_filter(\$date, 'is_int')) == 2) && (sort(\$date) === true))
{
\$result = array_fill_keys(explode('|', \$keys), 0);

foreach (preg_grep('~^(?:year|month)~i', \$result) as \$key => \$value)
{
while (\$date[1] >= strtotime(sprintf('+%u %s', \$value + 1, \$key), \$date[0]))
{
++\$value;
}

\$date[0] = strtotime(sprintf('+%u %s', \$result[\$key] = \$value, \$key), \$date[0]);
}

foreach (preg_grep('~^(?:year|month)~i', \$result, PREG_GREP_INVERT) as \$key => \$value)
{
if ((\$value = intval(abs(\$date[0] - \$date[1]) / strtotime(sprintf('%u %s', 1, \$key), 0))) > 0)
{
\$date[0] = strtotime(sprintf('+%u %s', \$result[\$key] = \$value, \$key), \$date[0]);
}
}

return \$result;
}

return false;
}
``````

It runs two loops; the first one deals with the relative intervals (years and months) via brute-forcing, and the second one computes the additional absolute intervals with simple arithmetic (so it's faster):

``````echo humanize(date_dif('2007-03-24', '2009-07-31', 'second')); // 74300400 seconds
echo humanize(date_dif('2007-03-24', '2009-07-31', 'minute|second')); // 1238400 minutes, 0 seconds
echo humanize(date_dif('2007-03-24', '2009-07-31', 'hour|minute|second')); // 20640 hours, 0 minutes, 0 seconds
echo humanize(date_dif('2007-03-24', '2009-07-31', 'year|day')); // 2 years, 129 days
echo humanize(date_dif('2007-03-24', '2009-07-31', 'year|week')); // 2 years, 18 weeks
echo humanize(date_dif('2007-03-24', '2009-07-31', 'year|week|day')); // 2 years, 18 weeks, 3 days
echo humanize(date_dif('2007-03-24', '2009-07-31')); // 2 years, 4 months, 1 week, 0 days, 0 hours, 0 minutes, 0 seconds

function humanize(\$array)
{
\$result = array();

foreach (\$array as \$key => \$value)
{
\$result[\$key] = \$value . ' ' . \$key;

if (\$value != 1)
{
\$result[\$key] .= 's';
}
}

return implode(', ', \$result);
}
``````

#### @David Bélanger 2013-10-01 11:03:43

It does not support directly week because there's no need. 7 days is a week...

#### @Peter Mortensen 2014-04-09 00:04:16

Does it work for leap years?

#### @Alix Axel 2014-04-09 01:01:58

@PeterMortensen: It should work, but I make no guarantees. Set your timezone and give it a go.

#### @esc 2010-10-14 03:17:49

``````// If you just want to see the year difference then use this function.
// Using the logic I've created you may also create month and day difference
// which I did not provide here so you may have the efforts to use your brain.
// :)
\$date1='2009-01-01';
\$date2='2010-01-01';
echo getYearDifference (\$date1,\$date2);
function getYearDifference(\$date1=strtotime(\$date1),\$date2=strtotime(\$date2)){
\$year = 0;
while(\$date2 > \$date1 = strtotime('+1 year', \$date1)){
++\$year;
}
return \$year;
}
``````

#### @Peter Mortensen 2014-04-08 23:38:00

Does "strtotime('+1 year', \$date1)" take leap years into account?

#### @Konstantin Shegunov 2011-01-10 17:21:00

I'm using the following function which I wrote, when PHP 5.3 (respectively date_diff()) is not available:

``````        function dateDifference(\$startDate, \$endDate)
{
\$startDate = strtotime(\$startDate);
\$endDate = strtotime(\$endDate);
if (\$startDate === false || \$startDate < 0 || \$endDate === false || \$endDate < 0 || \$startDate > \$endDate)
return false;

\$years = date('Y', \$endDate) - date('Y', \$startDate);

\$endMonth = date('m', \$endDate);
\$startMonth = date('m', \$startDate);

// Calculate months
\$months = \$endMonth - \$startMonth;
if (\$months <= 0)  {
\$months += 12;
\$years--;
}
if (\$years < 0)
return false;

// Calculate the days
\$measure = (\$months == 1) ? 'month' : 'months';
\$days = \$endDate - strtotime('+' . \$months . ' ' . \$measure, \$startDate);
\$days = date('z', \$days);

return array(\$years, \$months, \$days);
}
``````

#### @enobrev 2010-10-18 13:52:21

I voted for jurka's answer as that's my favorite, but I have a pre-php.5.3 version...

I found myself working on a similar problem - which is how I got to this question in the first place - but just needed a difference in hours. But my function solved this one pretty nicely as well and I don't have anywhere in my own library to keep it where it won't get lost and forgotten, so... hope this is useful to someone.

``````/**
*
* @param DateTime \$oDate1
* @param DateTime \$oDate2
* @return array
*/
function date_diff_array(DateTime \$oDate1, DateTime \$oDate2) {
\$aIntervals = array(
'year'   => 0,
'month'  => 0,
'week'   => 0,
'day'    => 0,
'hour'   => 0,
'minute' => 0,
'second' => 0,
);

foreach(\$aIntervals as \$sInterval => &\$iInterval) {
while(\$oDate1 <= \$oDate2){
\$oDate1->modify('+1 ' . \$sInterval);
if (\$oDate1 > \$oDate2) {
\$oDate1->modify('-1 ' . \$sInterval);
break;
} else {
\$iInterval++;
}
}
}

return \$aIntervals;
}
``````

And the test:

``````\$oDate = new DateTime();
\$oDate->modify('+111402189 seconds');
var_dump(\$oDate);
var_dump(date_diff_array(new DateTime(), \$oDate));
``````

And the result:

``````object(DateTime)[2]
public 'date' => string '2014-04-29 18:52:51' (length=19)
public 'timezone_type' => int 3
public 'timezone' => string 'America/New_York' (length=16)

array
'year'   => int 3
'month'  => int 6
'week'   => int 1
'day'    => int 4
'hour'   => int 9
'minute' => int 3
'second' => int 8
``````

I got the original idea from here, which I modified for my uses (and I hope my modification will show on that page as well).

You can very easily remove intervals you don't want (say "week") by removing them from the `\$aIntervals` array, or maybe adding an `\$aExclude` parameter, or just filter them out when you output the string.

#### @Stephen Harris 2012-08-18 10:56:31

Unfortunately this doesn't return the same thing as DateInterval because of year/month overflows.

#### @Alix Axel 2012-11-01 19:07:07

@StephenHarris: I haven't tested this, but by reading the code I'm pretty confident it should return the same result - provided that you delete the `week` index in `\$aIntervals` (since `DateDiff` never uses that).

#### @khaldonno 2010-03-18 19:07:43

View Hours and Minuts and Seconds..

``````\$date1 = "2008-11-01 22:45:00";

\$date2 = "2009-12-04 13:44:01";

\$diff = abs(strtotime(\$date2) - strtotime(\$date1));

\$years   = floor(\$diff / (365*60*60*24));
\$months  = floor((\$diff - \$years * 365*60*60*24) / (30*60*60*24));
\$days    = floor((\$diff - \$years * 365*60*60*24 - \$months*30*60*60*24)/ (60*60*24));

\$hours   = floor((\$diff - \$years * 365*60*60*24 - \$months*30*60*60*24 - \$days*60*60*24)/ (60*60));

\$minuts  = floor((\$diff - \$years * 365*60*60*24 - \$months*30*60*60*24 - \$days*60*60*24 - \$hours*60*60)/ 60);

\$seconds = floor((\$diff - \$years * 365*60*60*24 - \$months*30*60*60*24 - \$days*60*60*24 - \$hours*60*60 - \$minuts*60));

printf("%d years, %d months, %d days, %d hours, %d minuts\n, %d seconds\n", \$years, \$months, \$days, \$hours, \$minuts, \$seconds);
``````

#### @Dolphin 2011-08-05 08:24:12

Probably this will not give the accurate result.

#### @rdlowrey 2012-03-24 17:50:42

And is a terrible solution unless you're forced to use a terribly outdated version of PHP ...

#### @Peter Mortensen 2014-04-08 23:07:11

Not so DRY. For instance, 60*60*24 is repeated 15 times. Long live copy-paste reuse!

#### @Peter Mortensen 2014-04-08 23:10:04

What about leap years? A year is not 365 days on average.

#### @Peter Mortensen 2014-04-08 23:16:46

This code assumes a month is 30 days on average. Even assuming 365 days for a year, an average month is 365 / 12 = 30.42 days (approx.).

#### @Peter Mortensen 2014-04-08 23:18:02

This code is dead wrong and should not be used for any serious purpose.

#### @Peter Mortensen 2014-04-08 23:23:47

Even if the constants were adjusted, it would still only be correct on average, and not between any two particular dates.

### [SOLVED] Finding the number of days between two dates

• 2010-01-11 08:06:57
• PHP Ferrari
• 724470 View
• 582 Score
• Tags:   php datetime

### [SOLVED] How do I calculate someone's age in C#?

• 2008-07-31 23:40:59
• Jeff Atwood
• 559429 View
• 1742 Score
• Tags:   c# .net datetime

### [SOLVED] How to find the last day of the month from date?

• 2009-11-06 10:27:50
• Mithun Sreedharan
• 405615 View
• 348 Score