检查日期/期间是否在另一个日期/期间内 - 是否可以提供更优雅的解决方案?

时间:2017-03-09 19:35:59

标签: php algorithm date calendar

我想知道这个编程问题是否有一个优雅的解决方案。

有一个事件的日期符合以下条件:

1) it can be 'from' - 'to'
2) OR it can be 'from' 
   AND (repeating at defined intervals n times OR indefinitely). 
   The interwals can be day/week/month or year

该活动有参与者。 (S)如果他不在,他可能有一个期限/日期。

1) the date can be 'from' - 'to'
2) the date can be only 'from'
3) the date can be only 'to'

我需要检查参与者的“不可用”日期(如果存在)是否与事件日期重叠。

现在这是一个hotchpotch或条件。代码没有完成,我将不得不添加更多。语言 - PHP。我正在使用DateTime PHP对象来比较日期。

在某种程度上可以改善这种情况还是条件是这种情况下唯一的方法?我不需要一个确切的代码,只是一个想法。

    if($event->recurring === '0') {
        // Non recurring event
        if($eventEndValid && $userFromValid && $userToValid) { $user->available = ($userFrom < $eventStart && $userTo < $eventStart) || ($userFrom >= $eventEnd && $userTo > $eventEnd); } 
        else if($userFromValid && $userToValid) { $user->available = ($userFrom < $eventStart) && ($userTo <= $eventStart); }
        else if(!$eventEndValid && !$userToValid) { $user->available = false; }
        else if(!$eventEndValid && !$userFromValid) { $user->available = $userTo <= $eventStart; } 
        else if($eventEndValid && !$userToValid) { $user->available = $userFrom >= $eventEnd; } 
        else if($eventEndValid && !$userFromValid) { $user->available = $userTo <= $eventStart; }
    } else {
        $dIntStr = 'P';
        switch($event->recurring_frequency) {
            case '1':
                $dIntStr .= '1D';
                break;
            case '2':
                $dIntStr .= '1W';
                break;
            case '3':
                $dIntStr .= '1M';
                break;
            case '4':
                $dIntStr .= '1Y';
                break;
        }
        // Case 1
        if(!$userToValid) { $user->available = false; }
        if((!$userFromValid && $userToValid)) { $user->available = $userTo <= $eventStart; }

        // Case 2 - number of intervals is unlimited
        if($event->recurring_frequency === '0') {
            if($userToValid && $userTo <= $eventStart) { $user->available = true; } 
            else if($userTo > $eventStart) {
                // If unavailability is between the intervals then true
                $user->available = true;
            } 
            else { $user->available = false; }
        }


        // Case 2 - number of intervals is limited
        $dateInterval = DateInterval($dIntStr);
        if($event->recurring_frequency === '0') {

        }


    }

1 个答案:

答案 0 :(得分:1)

您通常可以使用函数来缩短代码。但是,我认为课程更适合这个:

class DateRange{
  public $from, $to;

  public function inBetween($outer){
    return $this->from >= $outer->from && $this->to <= $outer->to;
  }

  function __construct($from, $to){
    if($a = $from->getTimestamp() == $b = $to->getTimestamp()){
      throw new \Exception('A period cannot be the same time');
    } else {
      if($a < $b){
        $this->from = $a;
        $this->to = $b;
      } else {
        $this->from = b;
        $this->to = $a;
      }
    }
  }
}

$today    = new Datetime();
$lastyear = (new Datetime())->modify('-1 year');
$from     = (new Datetime())->modify('-9 month');

$outer    = new DateRange($lastyear, $today);
$inner    = new DateRange($from, $today);

if($inner->inBetween($outer)){
  echo 'it is';
} else {
  echo 'it isnt';
}

您可以按照这种方式添加更多方法,例如inBetween()