At first, I can recommend you use Object-oriented programming to better structuration of your code and decomposition of the task. You can create an abstraction to work with the weekday time. For example:
class WeekDayTime
{
/** @var string[] map of the name of days and their number */
const DAY_MAP = [
'Mon' => 1,
'Tue' => 2,
'Wed' => 3,
'Thu' => 4,
'Fri' => 5,
'Sat' => 6,
'Sun' => 7
];
/** @var int number of the day */
private $dayNumber;
/** @var int amount of hours */
private $hours;
/** @var int amount of minutes */
private $minutes;
/** @var int amount of seconds */
private $seconds;
/**
* Constuctor
* @param string $day number of the day
* @param int $hours amount of hours
* @param int $minutes amount of minutes
* @param int $seconds amount of seconds
*/
public function __construct(string $day, int $hours, int $minutes, int $seconds)
{
assert(array_key_exists($day, static::DAY_MAP), 'The day is incorrect');
assert($hours < 24, 'The hours must be less than 24');
assert($minutes < 60, 'The hours must be less than 60');
assert($seconds < 60, 'The hours must be less than 60');
$this->dayNumber = static::DAY_MAP[$day];
$this->hours = $hours;
$this->minutes = $minutes;
$this->seconds = $seconds;
}
/**
* Get number of the day
* @return int number of the day
*/
public function getDayNumber(): int
{
return $this->dayNumber;
}
/**
* Get amount of hours
* @return int amount of hours
*/
public function getHours(): int
{
return $this->hours;
}
/**
* Get amount of minutes
* @return int amount of minutes
*/
public function getMinutes(): int
{
return $this->minutes;
}
/**
* Get amount of seconds
* @return int amount of seconds
*/
public function getSeconds(): int
{
return $this->seconds;
}
/**
* Check if the current week day time is less the a denined week day time
* @param WeekDayTime $value value which will be compared
* @return bool status of the checking
*/
public function isLessOrEqual(WeekDayTime $value): bool
{
$isLess = $this->dayNumber < $value->dayNumber;
$isLessOrEqual = $this->dayNumber === $value->getDayNumber()
&& $this->hours <= $value->getHours()
&& $this->minutes <= $value->getMinutes()
&& $this->seconds <= $value->getSeconds();
return $isLess || $isLessOrEqual;
}
/**
* Check if the current week day time is greater the a denined week day time
* @param WeekDayTime $value value which will be compared
* @return bool status of the checking
*/
public function isGreaterOrEqual(WeekDayTime $value): bool
{
$isGreater = $this->dayNumber > $value->dayNumber;
$isGreaterOrEqual = $this->dayNumber === $value->getDayNumber()
&& $this->hours >= $value->getHours()
&& $this->minutes >= $value->getMinutes()
&& $this->seconds >= $value->getSeconds();
return $isGreater || $isGreaterOrEqual;
}
}
It will be the object-value which will have information about the day of week and time and methods to compare objects of this class. After it, you can create a class to contain a range of weekday time. For example:
class WeekDayTimeRange
{
/** WeekDayTime range start */
private $start;
/** WeekDayTime range end */
private $end;
/**
* Constuctor
* @param WeekDayTime $start range start
* @param WeekDayTime $end range end
*/
public function __construct(WeekDayTime $start, WeekDayTime $end)
{
$this->start = $start;
$this->end = $end;
}
/**
* Check if a date-time occurs into the range
* @param DateTimeInterface the date-time which will be checked
* @return bool status of the checking
*/
public function inRange(DateTimeInterface $dateTime): bool
{}
}
As can you see this class has information about range start, range end and method to check the occurrence of any date-time into the range. If you want to check the occurrence into a range which has start value less then end value (for example from Monday to Friday) you can do the following implementation of inRange
method:
public function inRange(DateTimeInterface $dateTime): bool
{
$day = $dateTime->format('D');
$hours = $dateTime->format('H');
$minutes = $dateTime->format('i');
$seconds = $dateTime->format('s');
$weekDayTime = new WeekDayTime($day, $hours, $minutes, $seconds);
return $this->start->isLessOrEqual($weekDayTime) && $this->end->isGreaterOrEqual($weekDayTime);
}
But if you want to check the occurrence into a range which has start value greater then end value (for example from Friday to Monday) you should break range to two ranges: from range start to week end and from week start to range end and to check the occurrence of the date-time into both ranges. For example:
public function inRange(DateTimeInterface $dateTime): bool
{
$day = $dateTime->format('D');
$hours = $dateTime->format('H');
$minutes = $dateTime->format('i');
$seconds = $dateTime->format('s');
$weekDayTime = new WeekDayTime($day, $hours, $minutes, $seconds);
// if the range end is less then range start we break the current range to two range
if ($this->end->isLessOrEqual($this->start)) {
$range1 = new WeekDayTimeRange($this->start, new WeekDayTime('Sun', 23,59,59));
$range2 = new WeekDayTimeRange(new WeekDayTime('Mon', 0,0,0), $this->end);
return $range1->inRange($dateTime) || $range2->inRange($dateTime);
}
return $this->start->isLessOrEqual($weekDayTime) && $this->end->isGreaterOrEqual($weekDayTime);
}
Example of using:
// Date occurs into the range from Tuesday to Friday
$start = new WeekDayTime('Tue', 10, 0,0);
$end = new WeekDayTime('Fri', 14, 0,0);
$range = new WeekDayTimeRange($start, $end);
$range->inRange(DateTime::createFromFormat('Y-m-d H:i:s', '2019-10-03 10:00:00'));
// Date doesn't occur into the range from Tuesday to Friday
$start = new WeekDayTime('Tue', 10, 0,0);
$end = new WeekDayTime('Fri', 14, 0,0);
$range = new WeekDayTimeRange($start, $end);
$range->inRange(DateTime::createFromFormat('Y-m-d H:i:s', '2019-10-05 10:00:00'));
// Date doesn't occur into the range from Friday to Tuesday
$start = new WeekDayTime('Fri', 14, 0,0);
$end = new WeekDayTime('Tue', 10, 0,0);
$range = new WeekDayTimeRange($start, $end);
$range->inRange(DateTime::createFromFormat('Y-m-d H:i:s', '2019-10-03 10:00:00'));
// Date occurs into the range from Friday to Tuesday
$start = new WeekDayTime('Fri', 14, 0,0);
$end = new WeekDayTime('Tue', 10, 0,0);
$range->inRange(DateTime::createFromFormat('Y-m-d H:i:s', '2019-10-05 10:00:00'));
You can see demo at sandbox
$data->select_start_day
? – RunnymedeThursday-Wednesday
. – HuohThursday
14000
and end onWednesday
130000
. Again everything is dynamic – Huoh