Exclude dates from a php DatePeriod output

Ask about general coding issues or problems here.

Moderators: egami, macek, gesf

Post Reply
User avatar
glynszasz
New php-forum User
New php-forum User
Posts: 2
Joined: Sat May 25, 2019 11:34 pm
Location: Sydney, Australia
Contact:

Sun May 26, 2019 12:43 am

I have written a script that I am having troubles getting to work.

The idea behind the script is to display a list of dates generated by DatePeriod with some excluded (from the $exclude array). Hope my coments make the code clear.

For some reason that I can not fathom the excluding dates part does not seem to be working. Any help or advice would be greatly appreciated. Many thanks.


Code: Select all

<?php
/**
 * Function will give the day ($day) of the week (say monday) for the next 3 ($interval) months
 * current date (as in today) is excluded
 * @param int $interval number of months, e.g. 2
 * @param $day - expected to be a day of the week, e.g. Monday
 * @return object of type DatePeriod
*/
function getRepeatingDays($interval, $day) {
	 $theDay = 'next '.$day;
	 $endDate = new DateTime();
	 $interval = new DateInterval("P".$interval."M");
	 $endDate->add($interval);
	 return new DatePeriod(
		  new DateTime(),
		  DateInterval::createFromDateString($theDay),
		  $endDate,
		  DatePeriod::EXCLUDE_START_DATE
	 );
}

// $dateList is a call to get a list of mondays for the next 2 months
$dateList = getRepeatingDays("2", "monday");

// $exclude is an array of dates that are to be excluded from the results given by $dateList
$exclude = array(
	 new DateTime('6/17/19'),
	 new DateTime('8/7/19'),
);

// iterate over $dateList and remove the excluded dates. Output the non-excluded dates
foreach($dateList as $newDate){
	 if(!in_array($newDate, $exclude)) {
	 		//add to $output the date string as Monday, 03 June 2019, add a html line break
		  $output.= $newDate->format("l, d F Y")."<br>";
	 }   
}

// output a list of dates
echo $output;
Happy to help where I can.

User avatar
hyper
php-forum Fan User
php-forum Fan User
Posts: 834
Joined: Mon Feb 22, 2016 5:52 pm

Sun May 26, 2019 1:51 am

Add this to your code:

Code: Select all

var_dump($exclude);
var_dump($dateList);
add it just before the foreach loop:

Code: Select all

var_dump($exclude);
var_dump($dateList);
// iterate over $dateList and remove the excluded dates. Output the non-excluded dates
foreach($dateList as $newDate){

User avatar
glynszasz
New php-forum User
New php-forum User
Posts: 2
Joined: Sat May 25, 2019 11:34 pm
Location: Sydney, Australia
Contact:

Sun May 26, 2019 5:53 am

Many thanks for the reply @hyper

I looked at the var_dump of both objects and noticed that the common "date" property. I am not sure how to access that and then use it to do the comparison.

However I came up with the following equals comparison which $outputs just the 2 excluded dates ( :D progress). However if I change the comparison to be not equal I get a list of all the dates doubled including the $testDate only once. Not sure why this is happening. Any ideas.

Code: Select all

foreach($dateList as $newDate){
    $testDate="";
    $testDate = $newDate->format("l d F");
    foreach($exclude as $excludeDate){
        if($testDate == $excludeDate->format("l d F")) {
            $output.= $testDate." at 2:00pm <br>";
        }
    }
}
So the full code becomes:

Code: Select all

<?php
/**
 * Function will give the day ($day) of the week (say monday) for the next 3 ($interval) months
 * current date (as in today) is excluded
 * @param int $interval number of months, e.g. 2
 * @param $day - expected to be a day of the week, e.g. Monday
 * @return object of type DatePeriod
*/
function getRepeatingDays($interval, $day) {
	 $theDay = 'next '.$day;
	 $endDate = new DateTime();
	 $interval = new DateInterval("P".$interval."M");
	 $endDate->add($interval);
	 return new DatePeriod(
		  new DateTime(),
		  DateInterval::createFromDateString($theDay),
		  $endDate,
		  DatePeriod::EXCLUDE_START_DATE
	 );
}

// $dateList is a call to get a list of mondays for the next 2 months
$dateList = getRepeatingDays("2", "monday");

// $exclude is an array of dates that are to be excluded from the results given by $dateList
$exclude = array(
	 new DateTime('6/17/19'),
	 new DateTime('8/7/19'),
);
$output ="";
// iterate over $dateList and remove the excluded dates. Output the non-excluded dates
foreach($dateList as $newDate){
    $testDate="";
	// convert the $newDate to a string and use this to compare to all of the $exclude array
    $testDate = $newDate->format("l d F");
    foreach($exclude as $excludeDate){
        if($testDate !== $excludeDate->format("l d F")) {
            $output.= $testDate." at 2:00pm <br>";
        }
    }
}

// output a list of dates
echo $output;
which outputs the following. Note that each date is duplicated except the matched excluded date:
Monday 27 May at 2:00pm
Monday 27 May at 2:00pm
Monday 03 June at 2:00pm
Monday 03 June at 2:00pm
Monday 10 June at 2:00pm
Monday 10 June at 2:00pm
Monday 17 June at 2:00pm
Monday 24 June at 2:00pm
Monday 24 June at 2:00pm
Monday 01 July at 2:00pm
Monday 01 July at 2:00pm
Monday 08 July at 2:00pm
Monday 08 July at 2:00pm
Monday 15 July at 2:00pm
Monday 15 July at 2:00pm
Monday 22 July at 2:00pm
Monday 22 July at 2:00pm
Happy to help where I can.

User avatar
hyper
php-forum Fan User
php-forum Fan User
Posts: 834
Joined: Mon Feb 22, 2016 5:52 pm

Sun May 26, 2019 6:57 am

Common mistake:

Code: Select all

if ($testDate !== $excludeDate->format("l d F")) {
  $output.= $testDate." at 2:00pm <br>";
}
You're comparing each date in your $exclude array, so if the $testDate is not the same as the date contained in the $exclude array, it adds it to the $output string. If you have three exclude dates, it would output the date three times except for the one time it matches - in which case it will output twice.

chorn
php-forum Fan User
php-forum Fan User
Posts: 600
Joined: Fri Apr 01, 2016 2:18 am

Sun May 26, 2019 11:06 pm

As your periods include the time part starting at your current time like 9:03:12 i would recommend comparing the string representation within your exclusion list like

Code: Select all

$exclusion = ['2019-06-17', '2019-08-07'];
foreach(...){
 if(!in_array($date->format('Y-m-d'), $exclusion)) ...
}

Post Reply