我目前正在努力完成一项应该是基本任务的任务。我有一个开始日期,一个结束日期和一个计数。我需要计算第三个参数(计数)在这两个日期之间每小时减少多少次:就像这样,countOffers("2012-03-27 11:00:00", "2012-04-08 19:00:00", 200)每小时一次。
这一点,我想我们已经讨论好了。现在问题来了。
我们只希望在我们的网站开放时进行计数。这些时间存储在数组中,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点之间,这个值会下降。如果它已经过了那个时间,或者我们现在已经关闭了,我们只想减少到最后一个关闭时间(可能是昨天)。
发布于 2012-04-03 23:04:19
这不是最漂亮或最有效的代码,但我认为它能满足您的要求。
<?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);将额外参数保留为默认为当前时间。
https://stackoverflow.com/questions/9990047
复制相似问题