Как сгенерировать возможные даты доставки в PHP? - PullRequest
1 голос
/ 10 июля 2020

Я пытаюсь реализовать этот алгоритм для создания 3 возможных дат доставки заказа в моем магазине, которые пользователь может выбрать во время оформления заказа: Магазин доставляет с понедельника по пятницу. Сервер должен вернуть массив с 3 возможными датами доставки в соответствии со следующими правилами: 2) магазин доставляет с понедельника по пятницу

  1. , если заказ сделан до 10 часов утра, то он также может быть доставлен на в тот же день (если с понедельника по пятницу)

Я пробовал несколько путей, и это то, к чему я пришел. Может ли кто-нибудь помочь мне завершить этот алгоритм?

public function test(){
    $today = date();
    $todayCode = date('N'); 
    $possibleShippingDates = [];
    while(count($possibleShippingDates)<3) {
        if($todayCode <6) {
            array_push($possibleShippingDates, $today);
            //go to next day?
            // $today = today + 1 day
            // $todayCode = date('N', $today)
        }
    }
    return $possibleShippingDates;
}

Ответы [ 3 ]

2 голосов
/ 10 июля 2020

Если текущее время, когда пользователь переходит к оформлению заказа, превышает 10 часов утра, то соответствующим образом отрегулируйте исходную точку (текущее время).

Используйте для этого классы DateTime. Для этого вы можете использовать ->add() или ->modify():

$order_date = '2020-07-09 10:23:00'; // if no argument, it will use the current time
function getPossibleShippingDates($order_date = 'now', $num_day = 3) {
    $dates = [];
    $dt = new DateTime($order_date);
    
    if ($dt->format('H') >= 10) { // if ordered on or after 10, move to next day
        $dt->modify('+1 day');
    }
    if (in_array($dt->format('N'), [6, 7])) { // if ordered weekend, adjust to start monday
        $dt->modify('next monday');
    }
    
    $i = 1;
    while ($i <= $num_day) {
        if (!in_array($dt->format('N'), [6, 7])) { // skip shipping day on weekends
            $dates[$i++] = $dt->format('Y-m-d');
        }
        $dt->modify('+1 day');
    }

    return $dates;
}

$dates = getPossibleShippingDates($order_date);
print_r($dates);

Примечание: приведенный выше пример ввода заказан 9-го числа, но выходит за пределы 10 AM. Так что он перейдет к следующему, 10-му. Таким образом, он должен дать 10-е, пропустить выходные, затем 13-е и 14-е.

Array
(
    [1] => 2020-07-10
    [2] => 2020-07-13
    [3] => 2020-07-14
)

Sample Fiddle

0 голосов
/ 10 июля 2020

Другое решение, использующее рекурсию:

//returns 3 possible shippingdates
function getShippingDates(DateTime $date , array $shippingDates = [] , int $number =3)
{
if($number !== 0) {
    //if before 10 on working day and on weekday the shipping date is allowed
    if($date->format('H') < 10 && in_array($date->format('N'), [1,2,3,4,5])){
        $shippingDates[] = $date->format('Y-m-d');
        //create new DateTime object from original DateTime object without time
        $newDate = $date->modify('+1 day');
        return getShippingDates(new DateTime($newDate->format('Y-m-d')) , $shippingDates ,$number -1);
    }
    else {
        //create new DateTime object from original DateTime object without time
        $newDate = $date->modify('+1 day');
        return getShippingDates(new DateTime($newDate->format('Y-m-d')), $shippingDates , $number);
    }
}
else {
    return $shippingDates;
}
}

$dates= getShippingDates(new DateTime('2020-07-10'));
var_dump($dates);

$dates= getShippingDates(new DateTime($time = "now"));
var_dump($dates);
0 голосов
/ 10 июля 2020

ну, наверное, проще использовать класс DateTime, но вот решение без него, сочетающее date() с strtotime() функциями:

/*
    store delivers from monday to friday
    if hour is within 10 in the morning, order can be shipped same day
    gives 3 possible dates
*/

public function test(){
    // order date time, to fill with the real one (this is current datetime)
    $orderDateTime = date("Y/m/d H:i");
    // flag to control the first day to check:
    // only first day has hour condition (until 10 in the morning)
    $firstDay = true;
    // setting up empty array for shipping dates
    $possibleShippingDates = [];
    // do it until it reaches 3 dates in the array
    while(count($possibleShippingDates) < 3) {
        // it gets day of week and hour from the order date time
        $todayCode = date('N', strtotime($orderDateTime)); 
        $todayHour = date("H", strtotime($orderDateTime));
        // if code is 1-5 (monday-friday) but not 6-7 (saturday-sunday)
        if($todayCode <6) {
            // if hour (24h format) is within 10 in the morning
            // or if current check day isn't the first one
            if($todayHour < 10 || !$firstDay) {
                // add the date as possible shipping date (reformatting it in d/m/Y)
                array_push($possibleShippingDates, date("d/m/Y", strtotime($orderDateTime)));
            }
        }
        // let's increment the date to the next one:
        //  - strtotime can add 1 day to order date time
        //  - save it using date still considering hour
        $orderDateTime = date("Y/m/d H:i", strtotime($orderDateTime . " + 1 day"));
        // if that was the first day,
        if ($firstDay) {
            // next ones won't be
            $firstDay = false;
        }
    }
    // at the end, return all possible shipping dates
    return $possibleShippingDates;
}

надеюсь, это поможет ... приятных выходных ! :)

...