我正在从事一个PHP项目,我需要计算企业的营业时间,其中包括每周定期安排和特殊的非标准假期时间.我有两个数组:一个用于常规日程,另一个用于非标准时间.

Regular opening times array:

$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
];

Non-standard opening times array (for holidays etc.):

$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']
];

利用this question的一些灵感,我能够为非标准的开放时间数组制作这个:

// 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;

这似乎如预期的那样工作,但我仍然需要从每周开放时间中找到下一个最近的开放日期和时间,而且我完全不知道该如何做到.有人能提供一些线索吗?谢谢.

推荐答案

因此,给定日期和时间,您需要下次开放时间的日期和时间. 我假设特殊日期会优先于常规日期.

首先,我们按日期和时间(两个输入数组)排序. 接下来,给定参考日期和时间,我们会发现它是否属于特殊日期,并获取当天的最早时间.

如果该日期没有特殊日期,我们将在正常开放时间寻找同一工作日.

如果仍然没有找到(比如周三),我们就第二天try 一下.


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

    // day of week of $reference_datetime
    $reference_weekday = date('w', strtotime($reference_datetime));
    if ($reference_weekday === 0) {
        $reference_weekday = 7;
    }

    // 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

Php相关问答推荐

为什么PHP输出\n而不是实际创建一个新元素?

Laravel 11发送邮箱时奇怪的未定义数组键名称

未找到laravel cascadeOnEdit

从WooCommerce邮箱通知中的订单详细信息中删除产品列表

PHP邮件表单无法识别重音/特殊字符

以编程方式更新现有Yith WooCommerce Booking的状态

自定义WooCommerce帐户下载列表

Htaccess-重写对&api.php";的API请求以及对";web.php";的其他请求

Sylius php -如何将购物车传递到小枝模板(Sylius模板事件)

将客户重定向到自定义感谢页后的空白页

使用ESI的Symfony Sulu清漆

PHP 支持 APNG 文件吗?

在 WordPress 中将自定义帖子类型永久链接设置为 root

PHP - 计算非数值数组

防止使用woocommerce_checkout_process下单

为什么foreach循环会输出每个结果?

MySQLI bind_param导致的Cannot modify readonly property错误

docker |管道失败的 ubuntu 源列表

如何在不解压缩/重新压缩的情况下连接(连接)两个缩小的值

遇到特定键时修改二维数组以创建嵌套数据集