views:

3455

answers:

10

What is the best (date format independent way) in PHP to calculate difference in days between two dates in specified format.

I tried the following function:

function get_date_offset($start_date, $end_date)
{
  $start_time = strtotime($start_date);
  $end_time = strtotime($end_date);
  return round(($end_time-$start_time)/(3600*24));
}

It works ok on linux box, but when running under windows strtotime returns ''.

EDIT:

Input date is in mm/dd/yyyy format, but I would like to make it accept $format as a parameter.

I need only difference in days.

+1  A: 

I'm not sure what is considered best, since there is no built-in function in PHP for doing this, but some people have used gregoriantojd(), for example in this forum post.

csl
+3  A: 

The problem with PHP is that it doesn't have a definite DateTime type. You can use a Unix timestamp, or the built-in DateTime class, but they are pretty limited in their functionality. I expect that there should be some 3rd party classes with more extensive support for date-time calculations, but I haven't looked for it.

Using Unix timestamps for date (not time) calculations is also tricky. You'd have to discard the time part, but simply resetting to 00:00 is not safe because of daylight savings time (DST). DST has the effect that there are two days every year that don't have exactly 24 hours. Thus, when adding/subtracting dates you might end up with a value that does not divide evenly with 3600*24.

I'd suggest looking for some 3rd party class that has proper support for all this stuff. Date/Time calculations are awesome in their ugliness. :P

Vilx-
+4  A: 

The PEAR Date class offers all kinds of features for finding the differences between dates and about 1000 other things as well. The docs for it are here...

rikh
+2  A: 

The Zend Framework has the class Zend_Date for dealing with "date math". It works around system specific timestamp limits by using the BCMath extension, or if that's not available limits the timestamps by max float value for your system.

// example printing difference in days
require('Zend/Date.php');

$date1 = new Zend_Date();
$date1->set(2, Zend_Date::MONTH);
$date1->set(27, Zend_Date::DAY);
$date1->set(2008, Zend_Date::YEAR);

$date2 = new Zend_Date();
$date2->set(3, Zend_Date::MONTH);
$date2->set(3, Zend_Date::DAY);
$date2->set(2008, Zend_Date::YEAR);

echo ($date2->getTimestamp() - $date1->getTimestamp()) / (3600*24);
Ole J. Helgesen
Yep, definitely the best answer so far.
OIS
+4  A: 

If you do not want or you cannot use Zend Framework or Pear package try this function i hope this would help:

function dateDifference($date1, $date2)
{
    $d1 = (is_string($date1) ? strtotime($date1) : $date1);
    $d2 = (is_string($date2) ? strtotime($date2) : $date2);

    $diff_secs = abs($d1 - $d2);
    $base_year = min(date("Y", $d1), date("Y", $d2));

    $diff = mktime(0, 0, $diff_secs, 1, 1, $base_year);

    return array
    (
     "years"   => abs(substr(date('Ymd', $d1) - date('Ymd', $d2), 0, -4)),
     "months_total" => (date("Y", $diff) - $base_year) * 12 + date("n", $diff) - 1,
     "months"  => date("n", $diff) - 1,
     "days_total" => floor($diff_secs / (3600 * 24)),
     "days"   => date("j", $diff) - 1,
     "hours_total" => floor($diff_secs / 3600),
     "hours"   => date("G", $diff),
     "minutes_total" => floor($diff_secs / 60),
     "minutes"  => (int) date("i", $diff),
     "seconds_total" => $diff_secs,
     "seconds"  => (int) date("s", $diff)
    );
}
Irmantas
A: 

Let's not overengineer, guys.

$d1 = strtotime($first_date);
$d2 = strtotime($second_date);
$delta = $d2 - $d1;
$num_days = ($delta / 86400);
dirtside
It's the same as in question. Problem is that strtotime doesn't work on windows box the same way as on linux, and that it can't parse arbitrary date formats.
Dev er dev
+1  A: 

gregoriantojd() gives the same results as using strtotime(), see this blogpost for how to do it:

http://www.phpro.org/examples/Calculate-Age-With-PHP.html

Radek
+1  A: 

The following works for me. Believe I found it on the php.net docs somewhere.

*Edit - Woops, didn't see csl's post. This is the exact function from his link, must have been where I found it. ;)

//Find the difference between two dates
function dateDiff($startDate, $endDate)
{
    // Parse dates for conversion
    $startArry = date_parse($startDate);
    $endArry = date_parse($endDate);

    // Convert dates to Julian Days
    $start_date = gregoriantojd($startArry["month"], $startArry["day"], $startArry["year"]);
    $end_date = gregoriantojd($endArry["month"], $endArry["day"], $endArry["year"]);

    // Return difference
    return round(($end_date - $start_date), 0);
}
Magic Hat
+1  A: 

I was trying to calculate the difference of two dates for the purpose of showing the duration of an event. Most of the functions given on the problem fails if the event has a duration form friday at 17:00 to sunday at 15:00. My goal was to find the difference between the dates like:

date('Ymd',$end)-date('Tmd',$begining);

But that is likly to fail because there isn't 99 month in a year and 99 days in a month. I could convert the date string to UNIX timestamp and divide by 60*60*12, but some days have a greater or lesser number of hours, sometimes there's eaven a leap secound. So I made my own function using getdate() a function that returns an array of innformation about the timestamp.

/*
 * datediff($first,$last)
 * $first - unix timestamp or string aksepted by strtotime()
 * $last - unix timestamp or string aksepted by strtotime()
 * 
 * return - the difference in days betveen the two dates
 */
function datediff($first,$last){
 $first = is_numeric($first) ? $first : strtotime($first);
 $last  = is_numeric($last ) ? $last  : strtotime($last );
 if ($last<$first){
  // Can't calculate negative difference in dates
  return -1;
 }
 $first = getdate($first);
 $last =  getdate($last );
 // find the difference in days since the start of the year
 $datediff = $last['yday'] - $first['yday'];
 // if the years do not match add the appropriate number of days.
 $yearCountedFrom = $first['year'];
 while($last['year'] != $yearCountedFrom ){
  // Take leap years into account
  if( $yearCountedFrom % 4 == 0 && $yearCountedFrom != 1900 && $yearCountedFrom != 2100 ){
   //leap year
   $datediff += 366;
  }else{
   $datediff += 365;
  }
  $yearCountedFrom++;
 }
 return $datediff;
}

Concerning the GregorianToJD() function, it might work, but I feel a little bit uneasy since I do not understand how it work.

ivarne
A: 

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.

See Php Date Time - 7 Methods to Calculate the Difference between 2 dates

James - Php Development