首先,我可以推荐你使用面向对象的编程来更好地结构化你的代码和分解任务。您可以创建一个抽象来处理工作日时间。例如:
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;
}
}
它将是对象值,它将包含有关星期几和时间的信息以及比较此类对象的方法。在它之后,您可以创建一个包含一系列工作日时间的类。例如:
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
{}
}
如您所见,此类包含有关范围开始、范围结束和检查范围内任何日期时间出现的方法的信息。如果您想检查开始值小于结束值的范围(例如从星期一到星期五)的出现,您可以执行以下inRange
方法实现:
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);
}
但是,如果您想检查开始值大于结束值的范围(例如从星期五到星期一),您应该将范围分为两个范围:从范围开始到周末,从一周开始到范围结束,然后到检查日期时间在两个范围内的出现。例如:
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);
}
使用示例:
// 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'));
你可以在沙盒看到演示