I’m currently struggling with what should be a basic task. I have a start date, an end date and a count. I need to calculate how many times an hour the third parameter (the count) should decrease between the two dates: like so, countOffers("2012-03-27 11:00:00", "2012-04-08 19:00:00", 200) every hour.
That bit, I think we have covered OK. The problem comes now.
We only want the counting to occur when our website is open. These times are stored in an array, the 0 index is open and 1 is close. Also, the date is dynamically updated to 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
)
)
So every hour the counter will decrease, whilst we’re between the opening times. When we’re closed however, we need to calculate where the counter would be up to the closing time today.
openTimes has a variable called areWeOpen which we can use to check if we’re currently open or closed. We have some code however it doesn’t always seem to work:
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);
}
It’ll count properly, however it seems to struggle when we’re closed, it’ll continue to decrease. I know there must be a better way to do this, I just can’t figure it out. I’m over complicating the problem in my head too much I think.
*Edit: * Okay, here is a break down of what I’m trying to achieve:
During opening times (provided in an array) I need to decrease a value x amount of times during the day. If we’re closed, then we only want to decrease that value up until the last closing time.
We are given a start date, end date and the start number of the counter. Between say 9AM and 9PM each day, the value can decrease. If it’s past that time, or we’re currently closed, we only want to decrease till the last closing time (potentially yesterday).
This is not the prettiest or most efficient code, but I think it does what you are asking for.
To test, you can call
countOffers()with a fourth parameter string to use as the current time.Leave off the extra parameter to default to the current time.