PHP how can I get next date in this example?
문제
I have 2 shipping zones, A & B. Orders for zone A are delivered each Monday, Wednesday & Friday, whereas zone B is on Tuesday, Thursday, Saturday. For each order, the delivery day is scheduled for the NEXT AVAILABLE day, depending on the zone. Please consider that if someone places an order on Monday the goods will be delivered on the NEXT available date, that would be Tuesday for zone B and Wednesday for zone A.
BUT: If an order is placed later than 18:00 (6pm) and the customer's area is within the tomorrow's delivery zone, then we have to advance the delivery date to the next available day for that zone (because the order won't be ready yet, too short notice).
Here's the code and it works fine except for the last part where I need to check time, get the regular delivery date and compare it with tomorrow's date.
<?
$date = array(date("d"), date("m"), date("Y"));
$zones = array("A" => array(1 => "Monday",
3 => "Wednesday",
5 => "Friday")
,"B" => array(2 => "Tuesday",
4 => "Thursday",
6 => "Saturday"));
$found = false;
$days_plus = 1; // always begin from next day
// Retrieve last day from the zone
end($zones[$zone]); //Friday or Saturday
$last_day = key($zones[$zone]); //5 or 6
do {
$mk = mktime(0, 0, 0, $date[1], ($date[0] + $days_plus), $date[2]);
$week = date("w", $mk); // current day of week
if ($week <= $last_day) // if weekday not passed last day of zone
{
if (!isset($zones[$zone][$week]))
{
$days_plus++;
}
else
{
$found = true;
$day = $last_day;
}
}
else
{
$days_plus++;
}
} while (!$found);
$deliverydate = date("d/m/Y", $mk); // regular delivery date
$tomorrow = date('d/m/Y', strtotime('tomorrow'));
//Now, check if order is placed after 6pm
if ((date("d/m/Y", $mk)==$tomorrow) && (date('G') > 18)) {
// HERE'S my problem, how do I advance the
//delivery date to next day in the same zone?
}
echo $deliverydate;
?>
Note: I tried converting the loop into a function findNextDay($days_plus, $date, $last_day, $zone) so that I could call it again with a different $days_plus value (increased by x days) but I couldn't get it to work. For anyone interested here is the modified version
해결책
This is how I would do it.
NOTE
I didn't give a whole lot of time to figuring out the best way to handle all of the business rules, but all of my tests seemed to work.
<?php
error_reporting(E_ALL);
ini_set('display_errors','On');
date_default_timezone_set('America/Los_Angeles');
$zones = array('A', 'B');
$zone_key = array_rand($zones);
$zone = $zones[$zone_key];
function getDeliveryDate($zone, $d = NULL, $time = NULL) {
if ($time === NULL)
$time = date('G');
if ($d === NULL)
$now = strtotime('now');
else
$now = strtotime($d);
$d = date('w', $now);
$days = 1;
if ($zone == 'A') {
if ($d % 2) $days += 1;
else if ($time > 18) $days += 2;
if ($d + $days == 7) $days += 1;
elseif ($d + $days > 7) $days -= 1;
} else {
if (! ($d % 2)) $days += 1;
else if ($time > 18) $days += 2;
if ($d + $days > 7) $days += 1;
}
$delivery_date = strtotime("+${days}days", $now);
echo "For zone $zone, schedule on " . date('D', $now) . ", at $time, will deliver on " . date('m-d-Y', $delivery_date) . " which is a " . date('D', $delivery_date) . "\n";
}
$days = array('10/16/2011', '10/17/2011', '10/18/2011', '10/19/2011', '10/20/2011', '10/21/2011', '10/22/2011');
$times = array(17, 20);
foreach ($zones as $zone) {
foreach ($days as $d) {
foreach ($times as $t) {
getDeliveryDate($zone, $d, $t);
}
}
}