Sourcerer
Sourcerer

Reputation: 139

PHP removing values meeting specific conditon from array

So, long story short, I have an array of date objects ($occupied).

I want to compare these dates to a $now=dateTime() so that any $occupied[$i] that happens before $now will get removed. I have tried some solution with unset, another one with (a brand new) array_push(). Neither of it has worked, so i guess i am missing some logic apart from the obvious.. Any approach is welcome :) Here is interesting part of the code:

$occupied=["2016-02-19", "2016-02-20", "2016-02-21", "2016-02-18", "2016-02-19", "2016-02-20", "2016-02-21", "2016-03-30", "2016-03-25", "2016-03-26"].
$now = new DateTime();

my ideas included:

$now= new dateTime();
for($i=0;$i<count($occupied);$i++){
    $occupied[$i]=new dateTime($occupied[$i]);  
    $diff[$i] = $now->diff($occupied[$i]);
    echo $diff[$i]->format('%r%a');
    if(get_object_vars($diff[$i])["invert"]==1){
       unset($occupied[$i]);
      }
  }

and variations over the theme.. Apologize if it is trivial, my background is very basic... I have tried to avoid posting by reading PHP manual and some answers here featuring "remove values from array//remove elements by key" but I could not figure it out..

Thanks in advance!

Upvotes: 1

Views: 74

Answers (5)

haris
haris

Reputation: 3875

You could use a foreach loop instead of for loop.

<?php

$occupied = [
    "2016-02-19", "2016-02-20", "2016-02-21", 
    "2016-02-18", "2016-02-19", "2016-02-20", 
    "2016-02-21", "2016-03-30", "2016-03-25", 
    "2016-03-26"
];

$now = new DateTime();
$now = $now->format("Y-m-d");

foreach ($occupied as $k => $date) 
    if ($date < $now)
        unset($occupied[$k]);


print_r($occupied);

This returns:

Array
(
    [7] => 2016-03-30
    [8] => 2016-03-25
    [9] => 2016-03-26
)

Alternatively, and personally I would prefer, array_filter() method rather than traversing manually, as suggested by a lot of others.

Upvotes: 1

axiac
axiac

Reputation: 72226

This is a classic usage for array_filter(). And by the way, you can compare two DateTime objects directly, using the usual comparison operators. As long as they use the same timezone, PHP will produce the result you expect. (It produces correct results even if they don't use the same timezone, just that it's not as easy to compute them yourself without pen and paper when the timezones differ.)

Now, the code:

$occupied=["2016-02-19", "2016-02-20", "2016-02-21", "2016-02-18", "2016-02-19", "2016-02-20", "2016-02-21", "2016-03-30", "2016-03-25", "2016-03-26"];
$now = new DateTime();

$filtered = array_filter(
    $occupied,
    function ($date) use ($now) {
        // Keep only the items that are greater (later) than $now
        return $now <= new DateTime($date);
    }
);

print_r($filtered);

It displays (today is 2016-03-12):

Array
(
    [7] => 2016-03-30
    [8] => 2016-03-25
    [9] => 2016-03-26
)

Upvotes: 0

Matt Prelude
Matt Prelude

Reputation: 912

You can use array_filter for this:

$now   = new DateTime("2015-12-31"); // Giving $now a fixed value so the output is the same for people who read in 10 months, you can use DateTime().
$dates = [
    "2015-12-29",
    "2015-12-30",
    "2015-12-31",
    "2016-01-01"
];

$newerDates = array_filter($dates, function($dateString) use ($now) {
    $date = new DateTime($dateString);

    return $date > $now;
});

In this instance, $newerDates will contain "2016-01-01".

Upvotes: 1

Ryan
Ryan

Reputation: 400

I usually create a date, rather than datetime.

$now = date('Y-m-d');

...
if($occupied[$i] < $now){
    unset($occupied[$i]);
}

Upvotes: 0

alexander.polomodov
alexander.polomodov

Reputation: 5534

Use this code:

$occupied=["2016-02-19", "2016-02-20", "2016-02-21", "2016-02-18",
        "2016-02-19", "2016-02-20", "2016-02-21",
        "2016-03-30", "2016-03-25", "2016-03-26"];

$now = new DateTime();
$nowStr = $now->format("Y-m-d");

$occupiedFiltered = array_filter($occupied,
    function($item) use($nowStr){
        return $item > $nowStr;
    }
);

$occupiedFiltered will be

array(3) {
  [7]=>
  string(10) "2016-03-30"
  [8]=>
  string(10) "2016-03-25"
  [9]=>
  string(10) "2016-03-26"
}

Upvotes: 4

Related Questions