2012-04-03 57 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