I need to check if start/end date are in a range of dates without missing days/interruptions/holes between them.
$dates_list might be large (containing multiple years of days), so performance is important. Can use the latest PHP 8.1 if needed.
My $dates_list is already ordered chronologically in the array.
<?php
function dates_in_consecutive_range(string $start_date, string $end_date, array $dates_list): bool {
// If in consecutive range without missing days (holes), return true, else return false
// If either $start_date or $end_date or both is not in $dates_list, return false
return false;
}
$dates_list = [
'2022-03-11',
'2022-03-12',
'2022-03-13',
'2022-03-14',
'2022-03-18',
'2022-03-19',
];
$start_date = '2022-03-11';
$end_date = '2022-03-14';
var_dump(dates_in_consecutive_range($start_date, $end_date, $dates_list)); // true
$start_date = '2022-03-11';
$end_date = '2022-03-18';
var_dump(dates_in_consecutive_range($start_date, $end_date, $dates_list)); // false
$start_date = '2022-03-18';
$end_date = '2022-03-19';
var_dump(dates_in_consecutive_range($start_date, $end_date, $dates_list)); // true
$start_date = '2022-03-19';
$end_date = '2022-03-20';
var_dump(dates_in_consecutive_range($start_date, $end_date, $dates_list)); // false ($end_date not in $dates_list)
Example: https://3v4l.org/hfk5D#v8.1.3
CodePudding user response:
I think this should work, let me know if it doesnt. It returns true, true, true, false though which the second one in comments of your code states should return false but both values are within the array
<?php
function dates_in_consecutive_range(string $start_date, string $end_date, array $dates_list): bool {
// If in consecutive range without missing days (holes), return true, else return false
// If either $start_date or $end_date or both is not in $dates_list, return false
if(in_array($start_date, $dates_list) <= in_array($end_date, $dates_list)){
return true;
}
else {
return false;
}
}
$dates_list = [
'2022-03-11',
'2022-03-12',
'2022-03-13',
'2022-03-14',
'2022-03-18',
'2022-03-19',
];
$start_date = '2022-03-11';
$end_date = '2022-03-14';
var_dump(dates_in_consecutive_range($start_date, $end_date, $dates_list)); // true
$start_date = '2022-03-11';
$end_date = '2022-03-18';
var_dump(dates_in_consecutive_range($start_date, $end_date, $dates_list)); // false
$start_date = '2022-03-18';
$end_date = '2022-03-19';
var_dump(dates_in_consecutive_range($start_date, $end_date, $dates_list)); // true
$start_date = '2022-03-19';
$end_date = '2022-03-20';
var_dump(dates_in_consecutive_range($start_date, $end_date, $dates_list)); // false ($end_date not in $dates_list)
CodePudding user response:
What part of this are you having trouble with? Your comments have the logic so it is a matter of implementing them:
// If either $start_date or $end_date or both is not in $dates_list, return false
if (!in_array($start_date, $dates_list) || !in_array($end_date, $dates_list)) {
return false;
}
For iterating over the $dates_list
we can use the DateTime
class to create a range of dates between the $start_date
and $end_date
:
// If in consecutive range without missing days (holes), return true, else return false
$start_dt = new DateTime($start_date);
$end_dt = new DateTime($end_date);
$interval = DateInterval::createFromDateString('1 day');
$period = new DatePeriod($start_dt, $interval, $end_dt);
foreach ($period as $dt) {
$curr_date = $dt->format("Y-m-d");
if (!in_array($curr_date, $dates_list)) {
return false;
}
}
Put it all together and you get the following: https://3v4l.org/6FcL2#v8.1.3