2012-04-03 1 views
0

В настоящее время я борюсь с тем, что должно быть основной задачей. У меня есть дата начала, дата окончания и счет. Мне нужно рассчитать, сколько раз в час третий параметр (счет) должен уменьшаться между двумя датами: например, countOffers("2012-03-27 11:00:00", "2012-04-08 19:00:00", 200) каждый час.PHP Уменьшение количества между датами

Это бит, я думаю, что мы закрыли ОК. Проблема возникает сейчас.

Мы только хотим, чтобы подсчет произошел, когда наш сайт открыт. Эти времена хранятся в массиве, индекс 0 открыт и 1 близок. Кроме того, дата динамически обновляется до now.

Array 
(
    [mon] => Array 
     (
      [0] => 2012-04-03 9:00 
      [1] => 2012-04-03 21:30 
     ) 

    [tue] => Array 
     (
      [0] => 2012-04-03 9:00 
      [1] => 2012-04-03 21:30 
     ) 

    [wed] => Array 
     (
      [0] => 2012-04-03 9:00 
      [1] => 2012-04-03 21:30 
     ) 

    [thu] => Array 
     (
      [0] => 2012-04-03 9:00 
      [1] => 2012-04-03 21.30 
     ) 

    [fri] => Array 
     (
      [0] => 2012-04-03 9:00 
      [1] => 2012-04-03 19:00 
     ) 

    [sat] => Array 
     (
      [0] => 2012-04-03 9:00 
      [1] => 2012-04-03 18:00 
     ) 

    [sun] => Array 
     (
      [0] => 2012-04-03 10:30 
      [1] => 2012-04-03 19:00 
     ) 

) 

Таким образом, каждый час счетчик будет уменьшаться, пока мы находимся между периодами открытия. Однако, когда мы закрыты, нам нужно рассчитать, где счетчик будет до сегодняшнего дня закрытия.

openTimes имеет переменную под названием areWeOpen, которую мы можем использовать, чтобы проверить, открыты ли мы в данный момент. У нас есть некоторый код, однако это не всегда похоже на работу:

function countOffers($start, $end, $deals) { 
    global $openTimes; 

    if(strtotime($end) < time()) return 1; 

    define('ONEHOUR', 1); 

    $totalDays = unixtojd(strtotime($end)) - unixtojd(strtotime($start)); 
    $daysBefore = unixtojd(time()) - unixtojd(strtotime($start)); 
    $daysAfter = unixtojd(strtotime($end)) - unixtojd(time()); 
    $startDay = strtolower(date("D", strtotime(date("Y-m-d", strtotime($start))))); 
    $totalHours = 0; 
    $hoursBefore = 0; 

    /* TOTAL HOURS */ 
    for($i = 0; $i <= $totalDays; $i++) { 
     $dayName = strtolower(date("D", strtotime(date("Y-m-d", strtotime($start)) . " +$i days"))); 
     $day = $openTimes->openDays[$dayName]; 
     if($i === 0) { 
      $startHour = explode(" ", $start); 
      $startHour = str_replace(array(":","3"), array(".","5"), $startHour[1]); 
      $endHour = explode(" ", $day[1]); 
      $endHour = str_replace(array(":","3"), array(".","5"), $endHour[1]); 
      $totalHours += $endHour - $startHour; 
     } else { 
      $tempHour = (strtotime($day[1]) - strtotime($day[0]))/3600; 
      $totalHours += (strtotime($day[1]) - strtotime($day[0]))/3600; 
     } 
    } 
    $perHour = round($deals/$totalHours, 1); 

    $today = 0; 
    if($openTimes->areWeOpen === FALSE && $openTimes->morning === FALSE) { 
     /* HOURS UP TO TODAY */ 
     for($i = 0; $i < $daysBefore; $i++) { 
      $day = $openTimes->openDays[strtolower(date("D", strtotime(date("Y-m-d", strtotime($start)) . " +$i days")))]; 
      $hoursBefore += (strtotime($day[1]) - strtotime($day[0]))/3600; 
     } 
    } elseif (strtotime($start) <= time()) { 
     /* HOURS UP TO YESTERDAY */ 
     for($i = 0; $i < ($daysBefore-1); $i++) { 
      $day = $openTimes->openDays[strtolower(date("D", strtotime(date("Y-m-d", strtotime($start)) . " +$i days")))]; 
      $hoursBefore += (strtotime($day[1]) - strtotime($day[0]))/3600; 
     } 

     if(strstr($start, date("Y-m-d", time()))) { 
      $today = ceil((time() - strtotime($start))/3600) - ONEHOUR; 
     } else { 
      $today = ceil((time() - strtotime($openTimes->openDays[strtolower(date("D", time()))][0]))/3600) - ONEHOUR; 
     } 
    } 
    $alreadyGone = $hoursBefore*$perHour; 

    $dealsLeft = $deals - (($hoursBefore*$perHour) + ($today*$perHour)); 
    if($dealsLeft < 0.5) $dealsLeft = 1; 

    return round($dealsLeft); 
} 

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

* Edit: * Хорошо, вот ломаются, что я пытаюсь достичь:

Во время открытия (при условии, в массиве) мне нужно для уменьшения значения x количество раз в течение день. Если мы закрыты, то мы хотим уменьшить это значение до последнего времени закрытия.

Нам даны дата начала, дата окончания и начальный номер счетчика. Между словом 9AM и 9PM каждый день значение может уменьшаться. Если это прошлое, или мы в настоящее время закрыты, мы хотим уменьшить только до последнего времени закрытия (возможно, вчера).

+3

Не в тему, но меня действительно интересует, почему у веб-сайта будут часы работы. – JJJ

+0

Поскольку сотрудники не принимают эти звонки? Мы ничего не продаем в Интернете. Наш сайт похож на онлайн-брошюру. – James

+1

@James вам может понравиться ... легко указать на своем сайте, чтобы не звонить в определенные часы ..? –

ответ

1

Это не самый красивый или эффективный код, но я думаю, что он делает то, о чем вы просите.

<?php 
/* test data 
$openTimes->openDays = array(
'mon' => array('2012-03-27 09:00', '2012-03-27 21:30'), 
'tue' => array('2012-03-27 09:00', '2012-03-27 21:30'), 
'wed' => array('2012-03-27 09:00', '2012-03-27 21:30'), 
'thu' => array('2012-03-27 09:00', '2012-03-27 21:30'), 
'fri' => array('2012-03-27 09:00', '2012-03-27 19:00'), 
'sat' => array('2012-03-27 09:00', '2012-03-27 18:00'), 
'sun' => array('2012-03-27 10:30', '2012-03-27 19:00'), 
); 
*/ 

function countOffers($start, $end, $deals, $now='') { 
    $start = new DateTime($start); 
    $end = new DateTime($end); 
    $now = new DateTime($now); 
    if ($now <= $start) { 
     return $deals; 
    } 
    if ($now >= $end) { 
     return 0; 
    } 
    $totalHours = openTimeBetween($start, $end)/60/60; 
    $hoursRemaining = openTimeBetween($now, $end)/60/60; 
    $perHour = $deals/$totalHours; 
    return (int)round($hoursRemaining * $perHour); 
} 

function openTimeBetween($start, $end) { 
    $totalTime = 0; 
    $today = new DateTime($start->format('Y-m-d H:i:s')); 
    while ($today <= $end) { 
     $totalTime += openTimeRemaining($today, $start, $end); 
     // set time to midnight the next day 
     $today->setTime(0, 0, 0); 
     $today->modify('+1 day'); 
    } 
    return $totalTime; 
} 

function openTimeRemaining($current, $minTime, $maxTime) { 
    global $openTimes; 
    // get the open/close times 
    $day = strtolower($current->format('D')); 
    list($open, $close) = $openTimes->openDays[$day]; 
    $open = new DateTime($open); 
    $close = new DateTime($close); 
    // set the date to be the same as $current 
    $open->setDate($current->format('Y'), $current->format('m'), $current->format('d')); 
    $close->setDate($current->format('Y'), $current->format('m'), $current->format('d')); 

    // if it's past closing time or past the maximum time 
    if ($current > $close || $current > $maxTime) { 
     return 0; 
    } 
    // if it's the first day, count from $minTime or $current, whichever is later 
    else if ($current->format('Y-m-d') === $minTime->format('Y-m-d')) { 
     $diff = max($minTime, $current, $open)->diff($close); 
    } 
    // if it's the last day, count to $maxTime or $close, whichever is earlier 
    else if ($current->format('Y-m-d') === $maxTime->format('Y-m-d')) { 
     $diff = max($current, $open)->diff(min($maxTime, $close)); 
    } 
    // otherwise count the total open time 
    else { 
     $diff = $open->diff($close); 
    } 
    return $diff->h * 60 * 60 + $diff->i * 60 + $diff->s; 
} 

Чтобы проверить, можно вызвать countOffers() с четвертой строки параметров для использования в качестве текущего времени.

$start = '2012-03-27 11:00:00'; 
$end = '2012-04-08 19:00:00'; 
$offers = 200; 
$now = '2012-04-04 17:00:00'; 
countOffers($start, $end, $offers, $now); 

Оставьте лишний параметр по умолчанию текущим временем.

+0

Это так близко, что я чувствую это. Однако я не могу заставить его вернуться к вчерашнему закрытию, если это утро, и мы закрыты. У меня будет скрипка! Но спасибо! – James

+0

Все отсортировано! Большое спасибо: 3 – James