user3450844
user3450844

Reputation: 83

Add missing dates to an array

I have the following array:

Array ( [2010-10-30] => 1 [2010-11-11] => 1 [2010-11-13] => 11 )

I am trying to fill in the array with all the missing dates between the first and last elements. I was attempting using the following but got nowhere:

foreach($users_by_date as $key => $value){
    $real_next_day = date($key, time()+86400);
    $array_next_day = key(next($users_by_date));
    if($real_next_day != $array_next_day){
      $users_by_date[$real_next_day] = $value;
    }
}

Upvotes: 2

Views: 7235

Answers (5)

user3450844
user3450844

Reputation: 83

This is the PHP 5.2 capable function I came up with that works.

Thanks guys

reset($users_by_date);
    $date = key($users_by_date);

    end($users_by_date);
    $end =  key($users_by_date);

    while(strtotime($date) <= strtotime($end)){
        $datearray[] = date("Y-m-d", strtotime($date));
        $date = date("Y-m-d", strtotime("+1 day", strtotime($date)));
    }

    foreach($datearray as $key => $value){
        if(!isset($users_by_date[$value])){
            $users_by_date[$value] = 0;
        }
    }
    ksort($users_by_date);

Upvotes: 0

erisco
erisco

Reputation: 14319

For indexes using timestamps, you can generate your array easily using the range function.

$startStamp = ...
$endStamp = ...
$oneDay = 60*60*24;

$timeIndexes = range($startStamp, $endStamp, $oneDay);
$filler = array_fill(0, count($timeIndexes), null);
$timeArray = array_combine($timeIndexes, $filler);

I am not sure what values you want in the array, but hopefully it is relatively straight-forward from here.

If you are going to be converting every timestamp to a formatted date string anyhow and would just prefer to use date strings in the first place, consider this modification.

$dateStringIndexes = array_map(
    function ($t) {
        return date('Y-m-d', $t);
    },
    $timeIndexes
);

Of course, since you are on PHP 5.2, you will likely have to compromise with a foreach loop instead of the closure.

Upvotes: 0

dnagirl
dnagirl

Reputation: 20456

The DateTime, DateInterval and DatePeriod classes can really help out here.

$begin=date_create('2010-10-30');
$end=date_create('2010-11-13');
$i = new DateInterval('P1D');
$period=new DatePeriod($begin,$i,$end);

foreach ($period as $d){
  $day=$d->format('Y-m-d');
  $usercount= isset($users_by_date[$day]) ? $users_by_date[$day] :0;
  echo "$day $usercount"; 
}

Upvotes: 8

Anti Veeranna
Anti Veeranna

Reputation: 11583

I have been waiting for a chance to try out DateTime and DateInterval objects in PHP 5.3, your question was the perfect opportunity to do just that. Note that this code will not work with PHP versions earlier than 5.3

<?php
$dates = array('2010-10-30' => 1, '2010-11-01' => 1, '2010-11-13' => 1);

// get start and end out of array
reset($dates);
$start = new DateTime(key($dates));

end($dates);
$end   = new DateTime(key($dates));

foreach (new DatePeriod($start, new DateInterval('P1D'), $end) as $date) {
    $dateKey = $date->format('Y-m-d'); // get properly formatted date out of DateTime object
    if (!isset($dates[$dateKey])) {
        $dates[$dateKey] = 1;
    }
}

print_r($dates);

Upvotes: 5

Jakub
Jakub

Reputation: 20475

The functions you are looking for (but not using in your example) are strtotime & diff

You would get the day range between your two dates $numdiff, and simply do something in a loop that would do:

for ($i=1; $i<=$numdiff; $i++) { 
   echo date("Y-m-d", strtotime("2010-10-30 +".$i." day"));
}

Result should be something like:

2010-10-31
2010-11-01
2010-11-02...

You could then pop that into your array as needed. Hope that gets you started in the right direction.

Upvotes: 1

Related Questions