2012-04-03 60 views
0

我目前正在努力應該完成什麼基本任務。我有開始日期,結束日期和計數。我需要計算每個小時第三個參數(計數)應在兩個日期之間減少多少次:如此,每小時countOffers("2012-03-27 11:00:00", "2012-04-08 19:00:00", 200)PHP在日期間減少計數

那位,我想我們已經覆蓋了OK。現在的問題出現了。

我們只希望計數發生在我們的網站是開放。這些時間存儲在一個數組中,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); 
} 

它會算正常,但是它似乎掙扎,當我們關閉,它會繼續減少。我知道必須有更好的方式來做到這一點,我無法弄清楚。我想我的頭腦太複雜了。

* 編輯:*好,這裏是一個休息的我想要實現了下來:

在開放時間(在陣列提供),我需要在減少的時間值x量那天。如果我們關閉,那麼我們只想減少該值直到最後的關閉時間。

我們給出了開始日期,結束日期和櫃檯的開始編號。在每天上午9點到晚上9點之間,價值可能會下降。如果已經過去了,或者我們目前關閉了,我們只想減少到最後關閉時間(可能是昨天)。

+3

偏離主題,但我真的很感興趣,爲什麼一個網站將有開放時間。 – JJJ 2012-04-03 09:01:40

+0

因爲沒有工作人員在接這些電話?我們不會在網上出售任何東西。我們的網站就像在線手冊。 – James 2012-04-03 09:17:12

+1

@詹姆斯你可能喜歡... ...輕鬆地在您的網站聲明不要打電話給某些特定的時間..? – 2012-04-03 09:35:42

回答

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 2012-04-04 08:04:50

+0

全部排序!非常感謝:3 – James 2012-04-04 09:47:36