786

How to find number of days between two dates using PHP?

YanDatsiuk
  • 1,885
  • 2
  • 18
  • 30
PHP Ferrari
  • 15,754
  • 27
  • 83
  • 149
  • 2
    The following SO questions might be of some help: - [How to calculate the date difference between 2 dates using php](http://stackoverflow.com/questions/676824/how-to-calculate-the-date-difference-between-2-dates-using-php) - [Dates difference with php](http://stackoverflow.com/questions/1803003/dates-difference-with-php) - [Calculate the difference between date/times in PHP](http://stackoverflow.com/questions/1074290/calculate-the-difference-between-date-times-in-php) - [Date Difference in php?](http://stackoverflow.com/questions/1940338/date-difference-in-php) - [Getting the difference betwee – Philip Morton Jan 11 '10 at 08:28
  • 26
    One liner: `(new DateTime("2010-01-11"))->diff(new DateTime("2019-08-19"))->days;` – But those new buttons though.. Aug 20 '19 at 01:08
  • @billynoah - this is the cleanest and more simple answer! – rolinger Feb 01 '20 at 11:51

35 Answers35

1099
$now = time(); // or your date as well
$your_date = strtotime("2010-01-31");
$datediff = $now - $your_date;

echo round($datediff / (60 * 60 * 24));
Cava
  • 5,346
  • 4
  • 25
  • 41
Adnan
  • 25,882
  • 18
  • 81
  • 110
  • 46
    I think returning a negative number of days provides relevant information. And you should be using `$your_date-$now`, if you want a future date to return a positive integer. – Tim Mar 02 '12 at 18:49
  • 25
    What about leap seconds? Not all days have exactly 24*60*60 seconds. This code might be sufficient for practical purposes but it's not exact in sone extremely rare edge cases. – Benjamin Brizzi Aug 01 '12 at 08:15
  • 60
    Forget leap seconds (no, actually consider those too) but this does NOT account for Daylight Saving Time changes! It can be off by an entire day over those boundaries every year. You need to use the DateTime classes. – Levi Dec 04 '12 at 03:34
  • @Levi is there any solution without using the `DateTime` class? (for those of us without PHP 5.3 yet) – Shackrock Mar 08 '13 at 21:49
  • @Shackrock the best solution I know is to set your timezone to GMT, then you can use strtotime('your date') to get numeric values and safely do math on the date values like in Adnan's solution. GMT does not observe DST or Leap Seconds. Be careful if you need to convert exact times instead of just dates from other timezones into GMT. – Levi Mar 09 '13 at 17:34
  • 2
    I found an error with this. $datediff = strtotime ("2014-04-09") - strtotime("2014-04-02"); echo floor($datediff/(60*60*24)); This returns 6 instead of 7!!!! – Alex Angelico Mar 10 '14 at 15:46
  • 1
    @AlexAngelico - not for me. I literally copied and pasted the code from your comment into an interactive php shell and php returned 7. – But those new buttons though.. Jul 23 '14 at 19:12
  • 7
    @billynoah Sorry, I never came back to update my comment. You have to be careful with daylight saving time zones. If you compare a date with daylight saving agains a date without it, instead of for example return 7 days it returns 6.9 days. Taking the floor returns 6 instead of 7. – Alex Angelico Jul 23 '14 at 22:45
  • 3
    KEEP IN MIND that using techniques that involve getting the Unix Timestamp (seconds from Jan 1, 1970) WILL FAIL IN TWENTY YEARS or so, when the signed 32 bit integer can no longer hold the value. This may not seem like a big deal right now, but eventually it will be a huge concern. CODE FOR THE FUTURE. Investigate using methods in the "Datetime" class. – UncaAlby May 05 '15 at 14:42
  • 2
    This is not a good practice. It yields incorrect results in a few situations. Use with caution ! – jowan sebastian Nov 20 '15 at 14:01
  • What is the format of date in `strtotime("2010-01-01");` ?, is it `Y-m-d` or `Y-d-m`?, what is the format of `strtotime` parameter. – 151291 Jan 23 '16 at 14:42
  • 1
    @151291 `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 – skirato Jun 30 '16 at 12:29
  • 2
    As discussed above, be very wary of DST, it will bite you. If the two dates are in two different DST settings, eg: 2016-03-01 (not DST) and 2016-09-30 (DST) then strtotime will use the current DST setting for each date and the diff will be off by 1/24 or .04166°. The solution is to either use the DateTime object (as discussed in other solutions) or force the time and timezone, eg: `$diff = (strtotime('2016-09-30 00:00:00 GMT') - strtotime('2016-03-01 00:00:00 GMT')) / (6 * 60 * 24);` – Yorick Sep 30 '16 at 21:17
  • 5
    Not only does strtotime() fail in 20 years, it's unusable right now. The OP specified Dates, not Time. Dates can be quite old. Here's a simpler answer: $NumberDays = gregoriantojd($EndM,$EndD,$EndY) - gregoriantojd($StartM,$StartD,$StartY); (for an inclusive range). Unlike the Datetime Class, Gregorian to Julian is available in v4 up. Valid range is 4714 B.C. to 9999 A.D. Beware of the funky parameter order (like you need that warning for php). – Guy Gordon Dec 08 '16 at 20:18
  • Out of curiosity: There's a pretty standard definition for seconds (since 1.1.1970) for easier calculations (aka: timestamp). Is there also a common standard for date enumeration for DAYS (since 1970 or 0 AD or whatever)...? – Frank N Mar 18 '17 at 08:56
  • Why do all my days result in 0 or -1? I have exactly what you got and when I echo the dates independently they show in the same format. – twan Mar 21 '17 at 14:24
  • 1
    I've been using this for awhile, and today it's giving incorrect results because the clocks went forward in the UK for british summer time! – dlofrodloh Mar 28 '17 at 14:24
  • 1
    Use `DateTime::diff()` instead (see other answers). This solution doesn't take leap days/seconds into account. – Giel Berkers Sep 08 '17 at 09:17
  • 1
    Very well. I got mine to work with your help . $diff = abs(strtotime($row['dateCreated'] ) - strtotime($row['incidenceDate'])); echo $diff/(60 * 60 * 24) .' days' ; – Asuquo12 Feb 13 '18 at 22:00
  • @UncaAlby, in 20 years I will be retired, I'll let you deal with that problem when time comes. I dealt with Y2K with forcing 4 digit years, however, after 20 years, there are developers who still use 2 digit years. – AaA Mar 12 '20 at 02:18
  • Don't forget about "Y2K38" problem when using "strtotime" function: it works only until 19. January 2038. – Aleksandar Belic Oct 08 '20 at 17:32
  • DateInterval is handling it and this is the only absolute unit it handles. For more complex cases, I created a CalendarHelper gist (no int, not time(), only sustainable DateInterval) => https://gist.github.com/Cartman34/b2a7e0e08b674b71a458c9a85a810855 – Loenix Mar 19 '21 at 11:27
696

If you're using PHP 5.3 >, this is by far the most accurate way of calculating the absolute difference:

$earlier = new DateTime("2010-07-06");
$later = new DateTime("2010-07-09");

$abs_diff = $later->diff($earlier)->format("%a"); //3

If you need a relative (signed) number of days, use this instead:

$earlier = new DateTime("2010-07-06");
$later = new DateTime("2010-07-09");

$pos_diff = $earlier->diff($later)->format("%r%a"); //3
$neg_diff = $later->diff($earlier)->format("%r%a"); //-3

More on php's DateInterval format can be found here: https://www.php.net/manual/en/dateinterval.format.php

Saksham Gupta
  • 6,969
  • 1
  • 12
  • 2
  • 17
    Note that because we're talking about time intervals not specific points in time, the format syntax is different from the date() and strftime() syntax. The time interval syntax can be found here: http://php.net/manual/en/dateinterval.format.php – Andrew Jun 04 '13 at 07:56
  • 2
    or in my case the number of days between is $date2->diff($date1)->format("%a") - 1 – xeo Feb 21 '14 at 02:07
  • 15
    Keep in mind that if you have times in your dates, this won't work as you might expect. For example, if you have an interval of 23:30 hours... and they are on different days, the difference will be 0. – Layke May 12 '14 at 09:47
  • 29
    If you need a _relative_ number of days (negative when `$date1` is anterior to `$date2`), then use `$diff = $date2->diff($date1)->format("%r%a");` instead. – Socce Apr 24 '15 at 09:06
  • 1
    What is the format of date in `DateTime("2010-07-06")` ?, is it `Y-m-d` or `Y-d-m`?, what is the format of `DateTime` parameter. which one is day ? – 151291 Jan 23 '16 at 14:43
  • 1
    @151291 A bit late, but a good rule of thumb when trying to figure what seems like a standarized time format (i.e. "YYYY-??-??") is "YYYY-mm-dd", since numerically it's the ordered way the calendar dates are going to be ordered... Or you can check your documentation :) – El Gucs Apr 26 '16 at 05:37
  • 1
    If you already have DateTime objects with time in it (aside from date) like in @Layke comment, and you still want to count calendar days diff, you can cast both of them with something like $date1 = new DateTime($dateWithTime1->format('Y-m-d')) and then compare. – Konrad Gałęzowski Jan 26 '17 at 07:35
  • 2
    This function failed 0 of its 14603 tests between 1980 and 2020. – LSerni Nov 09 '17 at 21:42
  • One should also note, that this method can not be used to determine "booked days" for example, if formatted with ('%a'). "2022-01-01" differs 0 to "2022-01-01". A lot of people would expect 1. Guess that is a general problem of understanding "between" two things. Try to sit down on a chair between two chairs if there are only two ^^. – aProgger Jun 03 '22 at 08:49
  • Also works with `$date2->diff($date1)->d;` Tested in PHP 7.4 ;) – csr-nontol Feb 03 '23 at 16:47
  • 1
    @csr-nontol please do not use `->d` in this scenario, as the days reset to zero every month. 34 days will result in `->m = 1` and `->d = 3`. Using `->a` gives you the total amount of days. – jerome2710 Feb 21 '23 at 15:42
  • @jerome2710 Thanks! Yes, I tested (today) this: `$date1 = new DateTime('2023-01-01'); $date2 = new DateTime(date('Y-m-d'));` and then: `$days_diff = $date2->diff($date1)->d;` the result **21**! But there is another way: replace `->d` by `->days` and the result is **52**, as expected ;) – csr-nontol Feb 22 '23 at 05:28
195

From PHP Version 5.3 and up, new date/time functions have been added to get difference:

$datetime1 = new DateTime("2010-06-20");

$datetime2 = new DateTime("2011-06-22");

$difference = $datetime1->diff($datetime2);

echo 'Difference: '.$difference->y.' years, ' 
                   .$difference->m.' months, ' 
                   .$difference->d.' days';

print_r($difference);

Result as below:

Difference: 1 years, 0 months, 2 days

DateInterval Object
(
    [y] => 1
    [m] => 0
    [d] => 2
    [h] => 0
    [i] => 0
    [s] => 0
    [invert] => 0
    [days] => 367
)

Hope it helps !

duplode
  • 33,731
  • 7
  • 79
  • 150
Aditya P Bhatt
  • 21,431
  • 18
  • 85
  • 104
  • 8
    Yes, this seems better than accepted answer, which doesn't work in some cases. Like: $from='2014-03-01'; $to='2014-03-31'; – MBozic May 30 '14 at 14:51
  • 1
    I agree, so easy to follow and works great!!! Just don't forget to use the date_default_timezone_set() function or it will give you strange results based on UTC time. – zeckdude Apr 23 '15 at 04:50
  • 2
    This function failed 0 of 14603 tests between 1980 and 2020. – LSerni Nov 09 '17 at 21:38
  • This is not always correct. Try: ```$fromDate = "2020-08-29"; $toDate = "2021-03-02"; returns 0 years, 6 months, 4 days. But it should be 6 months, 2 days ``` – Sadee Jul 23 '20 at 17:37
  • `[days]` is always an integer? – svelandiag Oct 22 '20 at 20:51
  • If you want rounded days difference correct answer would be `$daysRounded = ($difference->invert ? -1 : 1) * ($difference->days + ($difference->h >= 12 ? 1 : 0));` – Collector Mar 24 '21 at 09:25
182

TL;DR do not use UNIX timestamps. Do not use time(). If you do, be prepared should its 98.0825% reliability fail you. Use DateTime (or Carbon).

The correct answer is the one given by Saksham Gupta (other answers are also correct):

$date1 = new DateTime('2010-07-06');
$date2 = new DateTime('2010-07-09');
$days  = $date2->diff($date1)->format('%a');

Or procedurally as a one-liner:

/**
 * Number of days between two dates.
 *
 * @param date $dt1    First date
 * @param date $dt2    Second date
 * @return int
 */
function daysBetween($dt1, $dt2) {
    return date_diff(
        date_create($dt2),  
        date_create($dt1)
    )->format('%a');
}

With a caveat: the '%a' seems to indicate the absolute number of days. If you want it as a signed integer, i.e. negative when the second date is before the first, then you need to use the '%r' prefix (i.e. format('%r%a')).


If you really must use UNIX timestamps, set the time zone to GMT to avoid most of the pitfalls detailed below.


Long answer: why dividing by 24*60*60 (aka 86400) is unsafe

Most of the answers using UNIX timestamps (and 86400 to convert that to days) make two assumptions that, put together, can lead to scenarios with wrong results and subtle bugs that may be difficult to track, and arise even days, weeks or months after a successful deployment. It's not that the solution doesn't work - it works. Today. But it might stop working tomorrow.

First mistake is not considering that when asked, "How many days passed since yesterday?", a computer might truthfully answer zero if between the present and the instant indicated by "yesterday" less than one whole day has passed.

Usually when converting a "day" to a UNIX timestamp, what is obtained is the timestamp for the midnight of that particular day.

So between the midnights of October 1st and October 15th, fifteen days have elapsed. But between 13:00 of October 1st and 14:55 of October 15th, fifteen days minus 5 minutes have elapsed, and most solutions using floor() or doing implicit integer conversion will report one day less than expected.

So, "how many days ago was Y-m-d H:i:s"? will yield the wrong answer.

The second mistake is equating one day to 86400 seconds. This is almost always true - it happens often enough to overlook the times it doesn't. But the distance in seconds between two consecutive midnights is surely not 86400 at least twice a year when daylight saving time comes into play. Comparing two dates across a DST boundary will yield the wrong answer.

So even if you use the "hack" of forcing all date timestamps to a fixed hour, say midnight (this is also done implicitly by various languages and frameworks when you only specify day-month-year and not also hour-minute-second; same happens with DATE type in databases such as MySQL), the widely used formula

 FLOOR((unix_timestamp(DATE2) - unix_timestamp(DATE1)) / 86400)

or

 floor((time() - strtotime($somedate)) / 86400)

will return, say, 17 when DATE1 and DATE2 are in the same DST segment of the year; but even if the hour:minute:second part is identical, the argument might be 17.042, and worse still, 16.958 when they are in different DST segments and the time zone is DST-aware. The use of floor() or any implicit truncation to integer will then convert what should have been a 17 to a 16. In other circumstances, expressions like "$days > 17" will return true for 17.042, even if this will look as if the elapsed day count is 18.

And things grow even uglier since such code is not portable across platforms, because some of them may apply leap seconds and some might not. On those platforms that do, the difference between two dates will not be 86400 but 86401, or maybe 86399. So code that worked in May and actually passed all tests will break next June when 12.99999 days are considered 12 days instead of 13. Two dates that worked in 2015 will not work in 2017 -- the same dates, and neither year is a leap year. And between 2018-03-01 and 2017-03-01, on those platforms that care, 366 days will have passed instead of 365, making 2018 a leap year (which it is not).

So if you really want to use UNIX timestamps:

  • use round() function wisely, not floor().

  • as an alternative, do not calculate differences between D1-M1-YYY1 and D2-M2-YYY2. Those dates will be really considered as D1-M1-YYY1 00:00:00 and D2-M2-YYY2 00:00:00. Rather, convert between D1-M1-YYY1 22:30:00 and D2-M2-YYY2 04:30:00. You will always get a remainder of about twenty hours. This may become twenty-one hours or nineteen, and maybe eighteen hours, fifty-nine minutes thirty-six seconds. No matter. It is a large margin which will stay there and stay positive for the foreseeable future. Now you can truncate it with floor() in safety.

The correct solution though, to avoid magic constants, rounding kludges and a maintenance debt, is to

  • use a time library (Datetime, Carbon, whatever); don't roll your own

  • write comprehensive test cases using really evil date choices - across DST boundaries, across leap years, across leap seconds, and so on, as well as commonplace dates. Ideally (calls to datetime are fast!) generate four whole years' (and one day) worth of dates by assembling them from strings, sequentially, and ensure that the difference between the first day and the day being tested increases steadily by one. This will ensure that if anything changes in the low-level routines and leap seconds fixes try to wreak havoc, at least you will know.

  • run those tests regularly together with the rest of the test suite. They're a matter of milliseconds, and may save you literally hours of head scratching.


Whatever your solution, test it!

The function funcdiff below implements one of the solutions (as it happens, the originally accepted one - it has been since unaccepted) in a real world scenario.

<?php
$tz         = 'Europe/Rome';
$yearFrom   = 1980;
$yearTo     = 2020;
$verbose    = false;

function funcdiff($date2, $date1) {
    $now        = strtotime($date2);
    $your_date  = strtotime($date1);
    $datediff   = $now - $your_date;
    return floor($datediff / (60 * 60 * 24));
}
########################################

date_default_timezone_set($tz);
$failures   = 0;
$tests      = 0;

$dom = array ( 0, 31, 28, 31, 30,
                  31, 30, 31, 31,
                  30, 31, 30, 31 );
(array_sum($dom) === 365) || die("Thirty days hath September...");
$last   = array();
for ($year = $yearFrom; $year < $yearTo; $year++) {
    $dom[2] = 28;
    // Apply leap year rules.
    if ($year % 4 === 0)   { $dom[2] = 29; }
    if ($year % 100 === 0) { $dom[2] = 28; }
    if ($year % 400 === 0) { $dom[2] = 29; }
    for ($month = 1; $month <= 12; $month ++) {
        for ($day = 1; $day <= $dom[$month]; $day++) {
            $date = sprintf("%04d-%02d-%02d", $year, $month, $day);
            if (count($last) === 7) {
                $tests ++;
                $diff = funcdiff($date, $test = array_shift($last));
                if ((double)$diff !== (double)7) {
                    $failures ++;
                    if ($verbose) {
                        print "There seem to be {$diff} days between {$date} and {$test}\n";
                    }
                }
            }
            $last[] = $date;
        }
    }
}

print "This function failed {$failures} of its {$tests} tests";
print " between {$yearFrom} and {$yearTo}.\n";

The result is,

This function failed 280 of its 14603 tests

Horror Story: the cost of "saving time"

It all began in late 2014. An ingenious programmer decided to save several microseconds off a calculation that took about thirty seconds at most, by plugging in the infamous "(MidnightOfDateB-MidnightOfDateA)/86400" code in several places. It was so obvious an optimization that he did not even document it, and the optimization passed the integration tests and somehow lurked in the code for several months, all unnoticed.

This happened in a program that calculates the wages for several top-selling salesmen, the least of which has a frightful lot more clout than a whole humble five-people programmer team taken together. On March 28th, 2015, the summer time zone engaged, the bug struck -- and some of those guys got shortchanged one whole day of fat commissions. To make things worse, most of them did not work on Sundays and, being near the end of the month, used that day to catch up with their invoicing. They were definitely not amused.

Infinitely worse, they lost the (already very little) faith they had in the program not being designed to surreptitiously shaft them, and pretended - and obtained - a complete, detailed code review with test cases ran and commented in layman's terms (plus a lot of red-carpet treatment in the following weeks).

What can I say: on the plus side, we got rid of a lot of technical debt, and were able to rewrite and refactor several pieces of a spaghetti mess that hearkened back to a COBOL infestation in the swinging '90s. The program undoubtedly runs better now, and there's a lot more debugging information to quickly zero in when anything looks fishy. I estimate that just this last one thing will save perhaps one or two man-days per month for the foreseeable future, so the disaster will have a silver, or even golden, lining.

On the minus side, the whole brouhaha costed the company about €200,000 up front - plus face, plus undoubtedly some bargaining power (and, hence, yet more money).

The guy responsible for the "optimization" had changed job in December 2014, well before the disaster, but still there was talk to sue him for damages. And it didn't go well with the upper echelons that it was "the last guy's fault" - it looked like a set-up for us to come up clean of the matter, and in the end, we remained in the doghouse for the rest of the year, and one of the team resigned at the end of that summer.

Ninety-nine times out of one hundred, the "86400 hack" will work flawlessly. (For example in PHP, strtotime() will ignore DST, and report that between the midnights of the last Saturday of October and that of the following Monday, exactly 2 * 24 * 60 * 60 seconds have passed, even if that is plainly not true... and two wrongs will happily make one right).

This, ladies and gentlemen, was one instance when it did not. As with air-bags and seat belts, you will perhaps never really need the complexity (and ease of use) of DateTime or Carbon. But the day when you might (or the day when you'll have to prove you thought about this) will come as a thief in the night (likely at 02:00 some Sunday in October). Be prepared.

LSerni
  • 55,617
  • 10
  • 65
  • 107
  • 14
    When I saw these answers I have thought I'm stupid and crazy because I always use DateTime, but you made me understand that using DateTime is the right way. Thank you – SyncroIT Apr 07 '17 at 11:23
  • Hey, everyone here, on SO, got here by searching in google `days between two days in php` or similar, just because life is too short to write everything yourself. – Denis Matafonov Dec 28 '18 at 22:55
  • 5
    Sometimes I wish we could favorite the answers instead of the question. – Clément Baconnier Dec 19 '19 at 07:42
152

Convert your dates to unix timestamps, then substract one from the another. That will give you the difference in seconds, which you divide by 86400 (amount of seconds in a day) to give you an approximate amount of days in that range.

If your dates are in format 25.1.2010, 01/25/2010 or 2010-01-25, you can use the strtotime function:

$start = strtotime('2010-01-25');
$end = strtotime('2010-02-20');

$days_between = ceil(abs($end - $start) / 86400);

Using ceil rounds the amount of days up to the next full day. Use floor instead if you want to get the amount of full days between those two dates.

If your dates are already in unix timestamp format, you can skip the converting and just do the $days_between part. For more exotic date formats, you might have to do some custom parsing to get it right.

Tatu Ulmanen
  • 123,288
  • 34
  • 187
  • 185
  • 3
    @toon81 - we use [Unix timestamps](http://en.wikipedia.org/wiki/Unix_time) to avoid such messes! ;) – Alastair Sep 18 '13 at 04:57
  • 7
    Let me elaborate: let's say that this morning at 3AM, almost all of Europe moved the clock back an hour. That means that today has an extra 3600 seconds, and that ought to be reflected in the UNIX timestamps. If it is, then that means that today will count for two days with the above way of computing the number of days. And I'm not even starting about leap seconds since neither PHP nor UNIX seem to account for those (which is IMO actually understandable). _TL;DR: not all days are 86,400 seconds long_. – toon81 Sep 18 '13 at 08:59
  • 2
    @toon81 There are NOT 3600 more seconds for that date. Nothing at all happens to the UNIX timestamp when going to or from DST. – nickdnk Dec 20 '15 at 20:43
  • 2
    If nothing happens to the UNIX timestamp, then you agree with me: the difference between the UNIX timestamp at 1PM on `$day` and the UNIX timestamp at 1PM on `$day+1` is not always 86400 seconds in timezones that observe DST. It may be 23 or 25 hours' worth of seconds instead of 24 hours. – toon81 Dec 21 '15 at 13:25
  • 2
    DON'T USE UNIX TIMESTAMP. See comments above for reasons. – UncaAlby Mar 13 '17 at 22:39
20

Easy to using date_diff

$from=date_create(date('Y-m-d'));
$to=date_create("2013-03-15");
$diff=date_diff($to,$from);
print_r($diff);
echo $diff->format('%R%a days');
Balaji D
  • 1,245
  • 13
  • 20
  • This is a good procedural way to do it using the DateTime class. It only lacks a clear use of the interval object (`$diff` variable in this case). Something like `if ($diff->days > 30) { [doyourstuff]; }` – El Gucs Sep 23 '16 at 04:26
17

Object oriented style:

$datetime1 = new DateTime('2009-10-11');
$datetime2 = new DateTime('2009-10-13');
$interval = $datetime1->diff($datetime2);
echo $interval->format('%R%a days');

Procedural style:

$datetime1 = date_create('2009-10-11');
$datetime2 = date_create('2009-10-13');
$interval = date_diff($datetime1, $datetime2);
echo $interval->format('%R%a days');
Paweł Tomkiel
  • 1,974
  • 2
  • 21
  • 39
user2182143
  • 992
  • 9
  • 10
12

Well, the selected answer is not the most correct one because it will fail outside UTC. Depending on the timezone (list) there could be time adjustments creating days "without" 24 hours, and this will make the calculation (60*60*24) fail.

Here it is an example of it:

date_default_timezone_set('europe/lisbon');
$time1 = strtotime('2016-03-27');
$time2 = strtotime('2016-03-29');
echo floor( ($time2-$time1) /(60*60*24));
 ^-- the output will be **1**

So the correct solution will be using DateTime

date_default_timezone_set('europe/lisbon');
$date1 = new DateTime("2016-03-27");
$date2 = new DateTime("2016-03-29");

echo $date2->diff($date1)->format("%a");
 ^-- the output will be **2**
Miguel Costa
  • 399
  • 4
  • 10
  • Very well and simple solution. It works better than `date_diff()` with `date_create()` functions for me, because `date_create()` doesn't work for date string formatted as 'd.m.Y' . I don't know why. – Falcon Jan 07 '21 at 11:29
11

Used this :)

$days = (strtotime($endDate) - strtotime($startDate)) / (60 * 60 * 24);
print $days;

Now it works

ridecar2
  • 1,968
  • 16
  • 34
PHP Ferrari
  • 15,754
  • 27
  • 83
  • 149
  • 14
    Very old comment above, but it is incorrect. StackOverflow **does** allow you to answer your own question (even when you *ask* your question). Answering the question yourself after somebody already posted the same solution is however considered rude. – Maarten Bodewes May 19 '14 at 18:37
  • This function failed 560 of its 14603 tests between 1980 and 2020. – LSerni Nov 09 '17 at 21:43
7

You can find dates simply by

<?php
$start  = date_create('1988-08-10');
$end    = date_create(); // Current time and date
$diff   = date_diff( $start, $end );

echo 'The difference is ';
echo  $diff->y . ' years, ';
echo  $diff->m . ' months, ';
echo  $diff->d . ' days, ';
echo  $diff->h . ' hours, ';
echo  $diff->i . ' minutes, ';
echo  $diff->s . ' seconds';
// Output: The difference is 28 years, 5 months, 19 days, 20 hours, 34 minutes, 36 seconds

echo 'The difference in days : ' . $diff->days;
// Output: The difference in days : 10398
6

I'm using Carbon in my composer projects for this and similar purposes.

It'd be as easy as this:

$dt = Carbon::parse('2010-01-01');
echo $dt->diffInDays(Carbon::now());
Arda
  • 6,756
  • 3
  • 47
  • 67
6

Calculate the difference between two dates:

$date1=date_create("2013-03-15");
$date2=date_create("2013-12-12");

$diff=date_diff($date1,$date2);

echo $diff->format("%R%a days");

Output: +272 days

The date_diff() function returns the difference between two DateTime objects.

5
$start = '2013-09-08';
$end = '2013-09-15';
$diff = (strtotime($end)- strtotime($start))/24/3600; 
echo $diff;
power66x
  • 75
  • 1
  • 1
4

You can try the code below:

$dt1 = strtotime("2019-12-12"); //Enter your first date
$dt2 = strtotime("12-12-2020"); //Enter your second date
echo abs(($dt1 - $dt2) / (60 * 60 * 24));
atymic
  • 3,093
  • 1
  • 13
  • 26
  • 2
    With older questions that have existing answers it is useful to explain what new aspect your answer brings to the question. If relevant it is also useful to acknowledge any changes that may have occurred since the question was asked. – Jason Aller Aug 05 '19 at 20:50
3

number of days between two dates in PHP

      function dateDiff($date1, $date2)  //days find function
        { 
            $diff = strtotime($date2) - strtotime($date1); 
            return abs(round($diff / 86400)); 
        } 
       //start day
       $date1 = "11-10-2018";        
       // end day
       $date2 = "31-10-2018";    
       // call the days find fun store to variable 
       $dateDiff = dateDiff($date1, $date2); 

       echo "Difference between two dates: ". $dateDiff . " Days "; 
2
function howManyDays($startDate,$endDate) {

    $date1  = strtotime($startDate." 0:00:00");
    $date2  = strtotime($endDate." 23:59:59");
    $res    =  (int)(($date2-$date1)/86400);        

return $res;
} 
Thor
  • 120
  • 1
  • 7
2

If you have the times in seconds (I.E. unix time stamp) , then you can simply subtract the times and divide by 86400 (seconds per day)

zmbush
  • 2,790
  • 1
  • 17
  • 35
2

Easiest way to find the days difference between two dates

$date1 = strtotime("2019-05-25"); 
$date2 = strtotime("2010-06-23");

$date_difference = $date2 - $date1;

$result =  round( $date_difference / (60 * 60 * 24) );

echo $result;
Love Kumar
  • 1,056
  • 9
  • 10
2
$diff = strtotime('2019-11-25') - strtotime('2019-11-10');
echo abs(round($diff / 86400));
premkumar
  • 99
  • 1
  • 4
  • 3
    Welcome to SO! When you reply to a post with just code, please explain it a little bit. The code you bring it is calculating on between 2019-11-10 and 2019-11-25. So it is not replying to the question. That´s why is good to explain your POV better than get downvoted. – David García Bodego Nov 25 '19 at 13:16
2

This code worked for me and tested with PHP 8 version :

function numberOfDays($startDate, $endDate) 
{
    //1) converting dates to timestamps
     $startSeconds = strtotime($startDate);
     $endSeconds = strtotime($endDate);
   
    //2) Calculating the difference in timestamps
    $diffSeconds = $startSeconds  - $endSeconds;
     
    
    //3) converting timestamps to days
    $days=round($diffSeconds / 86400);
    
      /*  note :
          1 day = 24 hours 
          24 * 60 * 60 = 86400 seconds
      */
   
    //4) printing the number of days
    printf("Difference between two dates: ". abs($days) . " Days ");
    
    return abs($days);
}
Anis KCHAOU
  • 830
  • 1
  • 11
  • 11
2

it's easy:

$dateFrom = new DateTime('2023-08-01');
$dateTo = new DateTime('2023-10-01');

echo $dateFrom->diff($dateTo)->days;
// result: 61
Arkadiusz G.
  • 1,024
  • 10
  • 24
2
$datediff = floor(strtotime($date1)/(60*60*24)) - floor(strtotime($date2)/(60*60*24));

and, if needed:

$datediff=abs($datediff);
animuson
  • 53,861
  • 28
  • 137
  • 147
Gratian
  • 45
  • 1
1

If you want to echo all days between the start and end date, I came up with this :

$startdatum = $_POST['start']; // starting date
$einddatum = $_POST['eind']; // end date

$now = strtotime($startdatum);
$your_date = strtotime($einddatum);
$datediff = $your_date - $now;
$number = floor($datediff/(60*60*24));

for($i=0;$i <= $number; $i++)
{
    echo date('d-m-Y' ,strtotime("+".$i." day"))."<br>";
}
Blo
  • 11,903
  • 5
  • 45
  • 99
Refilon
  • 3,334
  • 1
  • 27
  • 51
0

If you are using MySql

function daysSince($date, $date2){
$q = "SELECT DATEDIFF('$date','$date2') AS days;";
$result = execQ($q);
$row = mysql_fetch_array($result,MYSQL_BOTH);
return ($row[0]);

}

function execQ($q){
$result = mysql_query( $q);
if(!$result){echo ('Database error execQ' . mysql_error());echo $q;}    
return $result;

}

user462990
  • 5,472
  • 3
  • 33
  • 35
0

Here is my improved version which shows 1 Year(s) 2 Month(s) 25 day(s) if the 2nd parameter is passed.

class App_Sandbox_String_Util {
    /**
     * Usage: App_Sandbox_String_Util::getDateDiff();
     * @param int $your_date timestamp
     * @param bool $hr human readable. e.g. 1 year(s) 2 day(s)
     * @see http://stackoverflow.com/questions/2040560/finding-the-number-of-days-between-two-dates
     * @see http://qSandbox.com
     */
    static public function getDateDiff($your_date, $hr = 0) {
        $now = time(); // or your date as well
        $datediff = $now - $your_date;
        $days = floor( $datediff / ( 3600 * 24 ) );

        $label = '';

        if ($hr) {
            if ($days >= 365) { // over a year
                $years = floor($days / 365);
                $label .= $years . ' Year(s)';
                $days -= 365 * $years;
            }

            if ($days) {
                $months = floor( $days / 30 );
                $label .= ' ' . $months . ' Month(s)';
                $days -= 30 * $months;
            }

            if ($days) {
                $label .= ' ' . $days . ' day(s)';
            }
        } else {
            $label = $days;
        }

        return $label;
    }
}
Svetoslav Marinov
  • 1,498
  • 14
  • 11
0

Try using Carbon

$d1 = \Carbon\Carbon::now()->subDays(92);
$d2 = \Carbon\Carbon::now()->subDays(10);
$days_btw = $d1->diffInDays($d2);

Also you can use

\Carbon\Carbon::parse('')

to create an object of Carbon date using given timestamp string.

Arda
  • 6,756
  • 3
  • 47
  • 67
Shriganesh Shintre
  • 2,428
  • 3
  • 17
  • 16
0
$early_start_date = date2sql($_POST['early_leave_date']);


$date = new DateTime($early_start_date);
$date->modify('+1 day');


$date_a = new DateTime($early_start_date . ' ' . $_POST['start_hr'] . ':' . $_POST['start_mm']);
$date_b = new DateTime($date->format('Y-m-d') . ' ' . $_POST['end_hr'] . ':' . $_POST['end_mm']);

$interval = date_diff($date_a, $date_b);


$time = $interval->format('%h:%i');
$parsed = date_parse($time);
$seconds = $parsed['hour'] * 3600 + $parsed['minute'] * 60;
//        display_error($seconds);

$second3 = $employee_information['shift'] * 60 * 60;

if ($second3 < $seconds)
    display_error(_('Leave time can not be greater than shift time.Please try again........'));
    set_focus('start_hr');
    set_focus('end_hr');
    return FALSE;
}
Marco Santarossa
  • 4,058
  • 1
  • 29
  • 49
ranojan
  • 819
  • 8
  • 11
0
<?php
$date1=date_create("2013-03-15");
$date2=date_create("2013-12-12");
$diff=date_diff($date1,$date2);
echo $diff->format("%R%a days");
?>

used the above code very simple. Thanks.

Y. Joy Ch. Singha
  • 3,056
  • 24
  • 26
0
function get_daydiff($end_date,$today)
{
    if($today=='')
    {
        $today=date('Y-m-d');
    }
    $str = floor(strtotime($end_date)/(60*60*24)) - floor(strtotime($today)/(60*60*24));
    return $str;
}
$d1 = "2018-12-31";
$d2 = "2018-06-06";
echo get_daydiff($d1, $d2);
user3216114
  • 305
  • 4
  • 13
0

Using this simple function. Declare function

<?php
function dateDiff($firstDate,$secondDate){
    $firstDate = strtotime($firstDate);
    $secondDate = strtotime($secondDate);

    $datediff = $firstDate - $secondDate;
    $output = round($datediff / (60 * 60 * 24));
    return $output;
}
?>

and call this function like this where you want

<?php
    echo dateDiff("2018-01-01","2018-12-31");    

// OR

    $firstDate = "2018-01-01";
    $secondDate = "2018-01-01";
    echo dateDiff($firstDate,$secondDate);    
?>
Obaidul Haque
  • 916
  • 11
  • 18
-1
    // Change this to the day in the future
$day = 15;

// Change this to the month in the future
$month = 11;

// Change this to the year in the future
$year = 2012;

// $days is the number of days between now and the date in the future
$days = (int)((mktime (0,0,0,$month,$day,$year) - time(void))/86400);

echo "There are $days days until $day/$month/$year";
engineervix
  • 345
  • 2
  • 6
  • 17
-1

Looking all answers I compose universal function what working on all PHP versions.

if(!function_exists('date_between')) :
    function date_between($date_start, $date_end)
    {
        if(!$date_start || !$date_end) return 0;

        if( class_exists('DateTime') )
        {
            $date_start = new DateTime( $date_start );
            $date_end   = new DateTime( $date_end );
            return $date_end->diff($date_start)->format('%a');
        }
        else
        {           
            return abs( round( ( strtotime($date_start) - strtotime($date_end) ) / 86400 ) );
        }
    }
endif;

In the general, I use 'DateTime' to find days between 2 dates. But if in the some reason, some server setup not have 'DateTime' enabled, it will use simple (but not safe) calculation with 'strtotime()'.

Ivijan Stefan Stipić
  • 6,249
  • 6
  • 45
  • 78
  • There are no such servers – Your Common Sense Aug 08 '23 at 09:37
  • Shall we bet? There are some third-rate hosting companies that think they have the best security parameters and the best optimization. I've been developing WordPress plugins for the past 9 years and you won't believe the problems I've run into. I know what I'm talking about and I am at general web development for 20 years. – Ivijan Stefan Stipić Aug 08 '23 at 09:51
-1

I read all previous solutions, none of them use PHP 5.3 tools: DateTime::Diff and DateInterval::Days

DateInterval::Days contains exactly the right numbers of days between to date. It is not necessary to create something special and bizarre.

/**
 * We suppose that PHP is configured in UTC
 * php.ini configuration:
 * [Date]
 * ; Defines the default timezone used by the date functions
 * ; http://php.net/date.timezone
 * date.timezone = UTC
 * @link http://php.net/date.timezone
 */

/**
 * getDaysBetween2Dates
 *
 * Return the difference of days between $date1 and $date2 ($date1 - $date2)
 * if $absolute parameter is false, the return value is negative if $date2 is after than $date1
 *
 * @param DateTime $date1
 * @param DateTime $date2
 * @param Boolean $absolute
 *            = true
 * @return integer
 */
function getDaysBetween2Dates(DateTime $date1, DateTime $date2, $absolute = true)
{
    $interval = $date2->diff($date1);
    // if we have to take in account the relative position (!$absolute) and the relative position is negative,
    // we return negatif value otherwise, we return the absolute value
    return (!$absolute and $interval->invert) ? - $interval->days : $interval->days;
}

echo '<h3>2020-03-01 - 2020-02-01: 29 days as it\'s a standard leap year</h3>';
echo getDaysBetween2Dates(new DateTime("2020-03-01"), new DateTime("2020-02-01"), false);

echo '<h3>1900-03-01 - 1900-02-01: 28 days as it\'s a "standard" century</h3>';
echo getDaysBetween2Dates(new DateTime("1900-03-01"), new DateTime("1900-02-01"), false);

echo '<h3>2000-03-01 - 2000-02-01: 29 days as it\'s a century multiple of 400: 2000=400x5</h3>';
echo getDaysBetween2Dates(new DateTime("2000-03-01"), new DateTime("2000-02-01"), false);

echo '<h3>2020-03-01 - 2020-04-01: -28 days as 2020-03-01 is before 2020-04-01</h3>';
echo getDaysBetween2Dates(new DateTime("2020-02-01"), new DateTime("2020-03-01"), false);
-1

I have tried almost all of the ways as in answers given. But neither DateTime nor date_create gave me correct answers in all my test cases. Specially test with February & March dates or December & January dates.

So, I came-up with mixed solution.

public static function getMonthsDaysDiff($fromDate, $toDate, $includingEnding = false){
    $d1=new DateTime($fromDate);
    $d2=new DateTime($toDate);
    if($includingEnding === true){
        $d2 = $d2->modify('+1 day');
    }
    $diff = $d2->diff($d1);
    $months = (($diff->format('%y') * 12) + $diff->format('%m'));

    $lastSameDate = $d1->modify("+$months month");
    $days = date_diff(
        date_create($d2->format('Y-m-d')),
        date_create($lastSameDate->format('Y-m-d'))
    )->format('%a');

    $return = ['months' => $months,
        'days' => $days];
}

I know, performance wise this quite expensive. And you can extend it to get Years as well.

Sadee
  • 3,010
  • 35
  • 36
-4

This works!

$start = strtotime('2010-01-25');
$end = strtotime('2010-02-20');

$days_between = ceil(abs($end - $start) / 86400);
Jason Roman
  • 8,146
  • 10
  • 35
  • 40
cinthyasm
  • 21
  • 3