2017-03-09 26 views
2

我想知道是否有這個編程問題的優雅解決方案。檢查日期/時期是否在另一個日期/時期內 - 是否可以更優雅的解決方案?

有符合以下條件的事件的日期:

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' 

我需要檢查,如果參與者的「不可用」日期 - 如果有的話 - 重疊在活動日期的任何方式。

現在這是一個hotpotsch或條件。代碼沒有完成,我將不得不添加更多。語言 - 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

您通常可以使用函數來縮短代碼。不過我倒是覺得一類更適合這樣的:

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()

+0

謝謝。這種方法非常有效。最初我認爲創建一個新類會有太多代碼 - 這是真的 - 但現在代碼更易於閱讀和維護。代碼:[DateRangeHelper class](https://bitbucket.org/al2357/php_snippets/src/d947a38689605ca58d8da3e6a1401b7e37659630/DateRangeHelper/DateRangeHelper.php?at=master&fileviewer=file-view-default) – Alan

相關問題