1

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!

2
  • What exactly contains $occupied? You said it contains "date objects" but the code shows strings and uses them as strings. By "date object" I understand instances of class DateTime. Commented Mar 11, 2016 at 23:28
  • Yeah, my bad... $occupied is originally strings, then converted to objects via " new dateTime($objects[$i]);... Commented Mar 11, 2016 at 23:34

5 Answers 5

4

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"
}
Sign up to request clarification or add additional context in comments.

1 Comment

$now = new DateTime(); $nowStr = $now->format("Y-m-d"); is just a longer way to write $nowStr = date('Y-m-d');
1

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".

Comments

1

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.

1 Comment

$now = new DateTime(); $now = $now->format("Y-m-d"); is just a longer way to write $now = date('Y-m-d');
0

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
)

2 Comments

I am selecting this one as it is slightly more detailed and it helped me to understand the sintax. Anyway, as the first answer is almost equal and it has been more upvoted, if the community asks I will change to that one instead..
Accepting an answer is the privilege of the question author; you don't have to accept an answer or another because somebody tells you so. The community expresses its preferences by using votes. You can also vote all the answers you like. It is not an unusual situation when the accepted answer has less votes than other answers; it even happens sometimes that the accepted answer has negative rating (more down-votes than up-votes from the community members).
0

I usually create a date, rather than datetime.

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

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.