0

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?

Alfred
  • 21,058
  • 61
  • 167
  • 249
  • this is a duplicate question http://stackoverflow.com/questions/10595524/date-range-array-excluding-the-sunday-the-holiday-in-php?rq=1 – DevZer0 Jul 11 '13 at 15:06
  • If you use the Y-m-d format (like MySQL) then you can use `max($datesarray)` and `min($datesarray)` as the end and start. AND strtotime() is more globally useable with this as d-m-y and m-d-y are used formats BUT dont give the same strtotime results. __WARNING__ looking at you data `20-05-2013` you are using UK format so strtotime() will not work for you! – Waygood Jul 11 '13 at 15:07
  • you're lucky that strtotime isn't mangling those date values. Are those January 3rd and Jan 6th? or March 1st and June 1st? never EVER depend on strtotime to do the "right thing". – Marc B Jul 11 '13 at 15:14
  • 5 mins gone by, so couldn't update comment. I realise `-` separator is for UK format, but in previous PHP versions it didn't always work – Waygood Jul 11 '13 at 15:15
  • @Waygood can you post a working code which accepts my required date format d-m-y? – Alfred Jul 16 '13 at 15:42
  • http://stackoverflow.com/questions/2891937/strtotime-doesnt-work-with-dd-mm-yyyy-format `$timestamp = DateTime::createFromFormat('!d-m-Y', $date)->getTimestamp();` to convert each date to a timestamp. min and max will work on this too. `$date_diff = abs(max($timestampsarray)-min($timestampsarray)) / 86400;` – Waygood Jul 18 '13 at 08:50

3 Answers3

0

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.

Michael Kunst
  • 2,978
  • 25
  • 40
0

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"
}
hek2mgl
  • 152,036
  • 28
  • 249
  • 266
  • not working bro.. :( can you show a demo at codepad.org ? Here is your code http://codepad.org/XL9gkJ9d – Alfred Jul 16 '13 at 16:06
0

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]);
}
?>
Waygood
  • 2,657
  • 2
  • 15
  • 16