结合每周计划和 PHP 中的特殊日期查找下一个可用日期时间

问题描述 投票:0回答:1

我正在开发一个 PHP 项目,我需要计算一家企业的营业时间,其中包括每周的常规时间表和假期的特殊非标准时间。我有两个数组:一个用于常规时间表,另一个用于非标准时间。

定期开放时间数组:

$opening_times = [
    ['open' => '09:00:00', 'weekday' => 1], // Monday
    ['open' => '09:00:00', 'weekday' => 2], // Tuesday
    ['open' => '09:00:00', 'weekday' => 4], // Thursday, Wednesday is closed
    ['open' => '09:00:00', 'weekday' => 5], // Friday opening time 1
    ['open' => '16:00:00', 'weekday' => 5], // Friday opening time 2
    ['open' => '09:00:00', 'weekday' => 6], // Saturday
    ['open' => '09:00:00', 'weekday' => 7], // Sunday
];

非标准开放时间数组(节假日等):

$special_opening_times = [
    ['date' => '2024-04-24', 'open' => '08:00:00'],
    ['date' => '2024-04-27', 'open' => '08:00:00'],
    ['date' => '2024-04-28', 'open' => '09:00:00'],
    ['date' => '2024-04-30', 'open' => '07:00:00'],
    ['date' => '2024-04-25', 'open' => '11:00:00']
];

利用来自这个问题的一些灵感我能够为非标准开放时间数组制作这个:

// Your reference datetime
$reference_datetime = '2024-04-25 10:30:00';

// Array with dates and times
$special_opening_times = [
    ['date' => '2024-04-24', 'open' => '08:00:00'],
    ['date' => '2024-04-27', 'open' => '08:00:00'],
    ['date' => '2024-04-28', 'open' => '09:00:00'],
    ['date' => '2024-04-30', 'open' => '07:00:00'],
    ['date' => '2024-04-25', 'open' => '11:00:00'] // Same day, later time
];

// Function to sort datetimes
function datetime_sort($a, $b) {
    $a_datetime = strtotime($a['date'] . ' ' . $a['open']);
    $b_datetime = strtotime($b['date'] . ' ' . $b['open']);
    return $a_datetime - $b_datetime;
}

// Sort datetimes using the custom function
usort($special_opening_times, 'datetime_sort');

// Variable to hold the next closest datetime
$next_datetime = null;

// Loop through sorted datetimes and find the next closest datetime
foreach ($special_opening_times as $date_array) {
    $current_datetime = strtotime($date_array['date'] . ' ' . $date_array['open']);
    if (strtotime($reference_datetime) < $current_datetime) {
        $next_datetime = $date_array['date'] . ' ' . $date_array['open'];
        break;
    }
}

// Output the next closest datetime
echo $next_datetime;

这似乎按预期工作,但是我仍然需要从每周的开放时间中找到下一个最近的开放日期和时间,而且我完全不知道如何做到这一点。谁能透露一些信息。谢谢。

php arrays date datetime time
1个回答
0
投票

因此,给定日期和时间,您需要下一个开放时间的日期和时间。 我假设特殊日期会覆盖常规日期。

首先我们按日期和时间对两个输入数组进行排序。 接下来给定参考日期和时间,我们查找是否属于特殊日期,并获得这一天的最早可能时间。

如果该日期没有特殊日期,我们将寻找同一个工作日的正常营业时间。

如果仍然没有找到(比如周三),我们就在第二天尝试。

function getNextOpening($opening_times, $special_opening_times, $reference_datetime)
{

    // day of week of $reference_datetime
    $reference_weekday = date('w', strtotime($reference_datetime));

    // time of day of $reference_datetime
    $reference_time = date('H:i:s', strtotime($reference_datetime));

    // date of $reference_datetime
    $reference_date = date('Y-m-d', strtotime($reference_datetime));


    // sort $opening_times by weekday and open time
    usort($opening_times, function ($a, $b) {
        if ($a['weekday'] == $b['weekday']) {
            return strcmp($a['open'], $b['open']);
        }
        return $a['weekday'] - $b['weekday'];
    });

    // sort $special_opening_times by date and open time
    usort($special_opening_times, function ($a, $b) {
        if (strtotime($a['date']) == strtotime($b['date'])) {
            return strcmp($a['open'], $b['open']);
        }
        return strtotime($a['date']) - strtotime($b['date']);
    });

    // find next special date and opening times for SAME date of $reference_datetime
    foreach ($special_opening_times as $special_opening) {
        if ($special_opening['date'] == $reference_date) {
            if (strtotime($special_opening['open']) > strtotime($reference_time)) {
                return $special_opening['date'] . ' ' . $special_opening['open'];
            }
        }
    }

    // no special day, find by regular opening times
    foreach ($opening_times as $opening) {
        if ($opening['weekday'] == $reference_weekday) {
            if ($opening['open'] > $reference_time) {
                return $reference_date. " ". $opening['open'];
            }
        }
    }

    // add 1 day to $reference_date 
    $reference_date = date('Y-m-d', strtotime("+1 day", strtotime($reference_date)));
    return getNextOpening($opening_times, $special_opening_times, $reference_date);

}


$opening_times = [
    ['open' => '09:00:00', 'weekday' => 1], // Monday
    ['open' => '09:00:00', 'weekday' => 2], // Tuesday
    ['open' => '09:00:00', 'weekday' => 4], // Thursday, Wednesday is closed
    ['open' => '16:00:00', 'weekday' => 5], // Friday opening time 2
    ['open' => '09:00:00', 'weekday' => 5], // Friday opening time 1
    ['open' => '09:00:00', 'weekday' => 6], // Saturday
    ['open' => '09:00:00', 'weekday' => 7], // Sunday
];

$special_opening_times = [
    ['date' => '2024-04-24', 'open' => '08:00:00'],
    ['date' => '2024-04-27', 'open' => '08:00:00'],
    ['date' => '2024-04-28', 'open' => '09:00:00'],
    ['date' => '2024-04-30', 'open' => '07:00:00'],
    ['date' => '2024-04-25', 'open' => '11:00:00']
];

echo getNextOpening($opening_times, $special_opening_times, '2024-04-25 10:30:00') . "\n";      // 2024-04-25 11:00:00
echo getNextOpening($opening_times, $special_opening_times, '2024-04-26 10:30:00') . "\n";      // 2024-04-26 16:00:00
echo getNextOpening($opening_times, $special_opening_times, '2024-04-24 07:30:00') . "\n";      // 2024-04-24 08:00:00
echo getNextOpening($opening_times, $special_opening_times, '2024-04-24 08:30:00') . "\n";      // 2024-04-25 11:00:00
© www.soinside.com 2019 - 2024. All rights reserved.