2015-11-13 2 views
1

год Для отображения сельскохозяйственной продукции, которая доступна в «текущем сезоне», я могу спросить:С конца месяца и в начале месяца, без относительно конкретной

ли ('Y-m-d',strtotime('today')) больше $start_of_season и менее $end_of_season, и до тех пор, дата начала до даты окончания, логика проста.

$date_format = 'Y-m-d'; 
if ((date_i18n($date_format,strtotime('today')) > date_i18n($date_format,strtotime($start_of_season))) && 
    (date_i18n($date_format,strtotime('today')) < date_i18n($date_format,strtotime($end_of_season)))): 

# display the produce 

Но что, если я хочу игнорировать год и измерять в период с ноября по февраль? Если сегодня 1 декабря, то это больше, чем ноябрь, но это также больше февраля.

Моя первая попытка сказать,

  • если end_date больше датой_начала

    • если сегодня во второй половине года
      • Затем вызовите датой_окончания 12-31
    • еще
      • Вызовите start_date 01-01

Это код:

$date_format = 'm-d'; 
if (date_i18n($date_format,strtotime($start_of_season)) > date_i18n($date_format,strtotime($end_of_season))): 
    if (date_i18n($date_format,strtotime('today')) > date_i18n($date_format,strtotime('2000-06-01'))): 
     $end_of_season = '2000-12-31'; 
    else: 
     $start_of_season = '2000-01-01'; 
    endif; 
endif; 

if ((date_i18n($date_format,strtotime('today')) > date_i18n($date_format,strtotime($start_of_season))) && 
    (date_i18n($date_format,strtotime('today')) < date_i18n($date_format,strtotime($end_of_season)))): 

который, кажется, "работа" в большинстве случаев.

Но если есть вещь, кто сезон с декабря по июль и текущая дата 1 июля, то есть будет $start_of_season > $end_of_season, но так как это после того, как 1 июня $end_of_season будет установлен до 31 декабря, поставив нас вне из «in_season» окно отображения.

Я уверен, что существуют разумные, красноречивые способы сделать это и можно использовать некоторое просветление.

ответ

1

Лично я бы инкапсулировать эту логику и использовать объекты даты. Вот самый простой способ, о котором я мог думать в данный момент. Свойства класса являются общедоступными для краткости.

<?php 

date_default_timezone_set('America/New_York'); 

class Season { 

    public $startMonth; 
    public $startDay; 
    public $endMonth; 
    public $endDay; 

    public function setStart($month, $day) { 
     $this->startMonth = (int) $month; 
     $this->startDay = (int) $day; 
    } 

    public function setEnd($month, $day) { 
     $this->endMonth = (int) $month; 
     $this->endDay = (int) $day; 
    } 

    function isActiveForDate(DateTime $date) { 

     $seasonStartDate = new DateTime(sprintf('%d-%d-%d', $date->format('Y'), $this->startMonth, $this->startDay)); 
     $seasonEndDate = new DateTime(sprintf('%d-%d-%d', $date->format('Y'), $this->endMonth, $this->endDay)); 

     // Edge case 
     if ($this->startMonth > $this->endMonth) { 
      $seasonStartDate->modify('-1 year'); 

      // This line is only useful if you wish to calculate inclusively 
      if ($date == $seasonStartDate || $date == $seasonEndDate) return true; 

      // If this condition is true, no need to calculate anything 
      if ($date->format('n') < $this->startMonth && $date->format('n') >= $this->endMonth) { 
       return false; 
      } 

      $seasonEndDate->modify('+1 year'); 
     } 

     return ($date->getTimestamp() >= $seasonStartDate->getTimestamp() 
      && $date->getTimestamp() <= $seasonEndDate->getTimestamp()); 
    } 
} 

Определение сезона:

$season = new Season(); 
$season->setStart(11, 1); 
$season->setEnd(7, 1); 

И проверить результат:

echo ($season->isActiveForDate(new DateTime("2000-7-2"))) ? "pass" : "fail"; // fail 
echo ($season->isActiveForDate(new DateTime("2000-10-31"))) ? "pass" : "fail"; // fail 
echo ($season->isActiveForDate(new DateTime("2000-11-1"))) ? "pass" : "fail"; // pass 
echo ($season->isActiveForDate(new DateTime("2000-6-31"))) ? "pass" : "fail"; // pass 
+0

Я не знал о 'modify' метода для объектов DateTime. Это действительно приятное предложение. Адаптируйте его и высоко оценили. – MikeiLL

1

Вы можете создать массив допустимых месяцев. Затем проверьте, находится ли месяц в массиве разрешенных месяцев. Если да, вам просто нужно проверить, находитесь ли вы в первый или последний месяц сезона. Если в течение первого месяца вы должны проверить, больше ли день или равен стартовому дню. Если в последний месяц вы должны проверить, меньше или меньше дня, чем в конце дня.

Вот пример кода:

function getMonthArray($startMonth, $endMonth) { 
    $return = array(); 
    $return[] = $startMonth; 

    while($startMonth != $endMonth) { 
     $startMonth++; 
     if ($startMonth > 12) { 
      $startMonth = 1; 
     } 
     $return[] = $startMonth; 
    } 
    return $return; 
} 

function isInSeason($start, $end, $check) { 
    $month  = (int) substr($check, 0, 2); 
    $startMonth = (int) substr($start, 0, 2); 
    $endMonth = (int) substr($end, 0, 2); 
    if (in_array($month, getMonthArray($startMonth, $endMonth))) { 
     $day  = (int) substr($check, 3, 2);  
     if ($month == $startMonth) { 
      $startDay = (int) substr($start, 3, 2); 
      return ($day >= $startDay); 
     } elseif ($month == $endMonth) { 
      $endDay = (int) substr($end, 3, 2); 
      return ($day <= $endDay); 
     } else { 
      return TRUE; 
     } 
    } 
    return FALSE; 
} 

$start = '12-01'; 
$end = '06-30'; 

$check = '07-10'; 

if (isInSeason($start, $end, $check)) { 
    echo 'In season'; 
} else { 
    echo 'Not in season'; 
} 
1

Вы можете нормализовать ваши месяцев до начала сезона. Например, если начало вашего сезона - ноябрь (11-й месяц) и конец февраля (месяц 2), они нормализуются до 1-го и 4-го месяцев соответственно.Затем вы можете проверить каждый месяц против нормализованного года и посмотреть, попадает ли он в течение сезона.

$startMonth = 11; // November 
$endMonth = 2; // February 

$futureFactor = $startMonth - 1; 
$pastFactor = 13 - $startMonth; 

$months = []; 

// Create a normalized year to the start month. 
foreach (range(1,12) as $r) { 

    if ($r == $startMonth) { 
    $months[$r] = 1; 
    } 
    else { 
    $months[$r] = $r < $startMonth ? $r + $pastFactor : $r - $futureFactor; 
    } 
} 

// Check if December(12) is in season 
if ($months[12] >= $months[$startMonth] && $months[12] <= $months[$endMonth]) { 
    print "In season...\n"; 
} 
else { 
    print "Out of season...\n"; 
} 

Нормированный год Пример:

Array 
(
    [1] => 3 
    [2] => 4 
    [3] => 5 
    [4] => 6 
    [5] => 7 
    [6] => 8 
    [7] => 9 
    [8] => 10 
    [9] => 11 
    [10] => 12 
    [11] => 1 
    [12] => 2 
) 
Смежные вопросы