Alfred
Alfred

Reputation: 21396

How to find date difference excluding specific dates in array - PHP

I know how to calculate date difference using PHP like;

$newdate = "01-03-2013";
$olddate = "01-06-2013";
$date_diff = abs(strtotime($olddate)-strtotime($newdate)) / 86400;
echo $date_diff;

But suppose, if I have some dates in an array like;

$datesarray = array(10-05-2013, 20-05-2013, 12-08-2013);

etc., holding some specific dates, is it possible to calculate date difference excluding the dates in array along with the Sundays, if they lie in between the start and end dates?

Upvotes: 0

Views: 460

Answers (3)

Waygood
Waygood

Reputation: 2693

The following script creates and array of timestamps from your array of UK dates and then calculates the max and min timestamps to calculate the days difference.

If the timestamp defaults to 0, it is not added to the timestamp array, avoiding huge results for one bad date defaulting to the epoch I.e. When date is invalid or pre epoch 1/1/1970

<?php

$datesarray = array('10-05-2013', '20-05-2013', '12-08-2013');

$date_diff=0; // default for 0 or 1 dates
if( (is_array($datesarray)) && (sizeof($datesarray)>1) )
{
    $timestampsarray=array();
    reset($datesarray);
    while(list($key,$value)=each($datesarray))
    {
        $timestamp=timestamp_from_UK($value);
        if($timestamp!=0) $timestampsarray[$key]=$timestamp;
    }
    $date_diff = abs(max($timestampsarray)-min($timestampsarray)) / 86400;
}
echo $date_diff;

function timestamp_from_UK($ukdatetime)
{
    // where PHP is processing UK dates d-m-y correctly
    $ukdatetime=str_replace('/', '-', $ukdatetime);
    if(date("d", strtotime("1-2-1970"))==1) return strtotime($ukdatetime);

    // Fallback script for when PHP is NOT processing UK dates
    $success=false;
    if(!$success) $success=preg_match("/([0-9]{1,2})[^0-9]([0-9]{1,2})[^0-9]([0-9]{2,4})[^0-9]([0-9]{1,2})[^0-9]([0-9]{1,2})[^0-9]([0-9]{1,2})/", $ukdatetime, $matches);
    if(!$success) $success=preg_match("/([0-9]{1,2})[^0-9]([0-9]{1,2})[^0-9]([0-9]{2,4})[^0-9]([0-9]{1,2})[^0-9]([0-9]{1,2})/", $ukdatetime, $matches);
    if(!$success) $success=preg_match("/([0-9]{1,2})[^0-9]([0-9]{1,2})[^0-9]([0-9]{2,4})/", $ukdatetime, $matches);
    if(!$success) return 0;

    // ensure all values are set - to avoid invalid offset
    for($i=4;$i<=6;$i++)
    {
        if(!isset($matches[$i])) $matches[$i]=0;
    }
    // $matches[0] is the full matched string
    return mktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[1], $matches[3]);
}
?>

Upvotes: 0

hek2mgl
hek2mgl

Reputation: 158020

I would use the DateTime class in a custom function like this:

function dates_between(DateTime $start, DateTime $end, $format = 'm-d-Y') {
    $date = $start;
    $dates = array();
    $oneDay = new DateInterval('P1D');
    // push all dates between start and end to the result
    while(($date = $date->add($oneDay)) < $end) {
        $dates []= $date->format($format);
    }
    return $dates;
}

Example usage:

$now = new DateTime();
$nextWeek = new DateTime('+1 week');
var_dump(dates_between($now, $nextWeek));

Output:

array(6) {
  [0] =>
  string(10) "07-12-2013"
  [1] =>
  string(10) "07-13-2013"
  [2] =>
  string(10) "07-14-2013"
  [3] =>
  string(10) "07-15-2013"
  [4] =>
  string(10) "07-16-2013"
  [5] =>
  string(10) "07-17-2013"
}

Upvotes: 0

Michael Kunst
Michael Kunst

Reputation: 2988

just loop through the $datesarray and check for each one if it's between the $olddate and $newdate. If so, increase a $counter variable (which starts at 0, obviously). Then $date_diff - $counter will give you the expected result.

Upvotes: 0

Related Questions