根据营业时间确定业务是否开放/关闭

时间:2013-02-15 23:05:57

标签: php date datetime strtotime

如果时间是AM到PM(例如:上午11点到晚上10点),我的代码工作正常,但如果操作时间是AM到AM(例如:上午9点 - 凌晨1点),它会中断。这是我的代码:

$datedivide = explode(" - ", $day['hours']); //$day['hours'] Example 11:00 AM - 10:00 PM
$from = ''.$day['days'].' '.$datedivide[0].'';
$to = ''.$day['days'].' '.$datedivide[1].'';
$date = date('l g:i A');
$date = is_int($date) ? $date : strtotime($date);
$from = is_int($from) ? $from : strtotime($from);
$to = is_int($to) ? $to : strtotime($to);
if (($date > $from) && ($date < $to) && ($dateh != 'Closed')) {
    ?>
    <script type="text/javascript">
    $(document).ready(function(){
        $('.entry-title-container').append('<div class="column two"><h2 style="color:green;text-align: left;margin: 0;">OPEN<br /><span style="color:#222;font-size:12px;display: block;">Closes at <?php echo $datedivide[1]; ?></span></h2></div><br clear="all" />');
    });
    </script>
    <?php
}

7 个答案:

答案 0 :(得分:36)

您首先需要创建一个数组,该数组将保存您一周中的几天以及它们各自的关闭/开放时间范围。

/**
 * I setup the hours for each day if they carry-over)
 * everyday is open from 09:00 AM - 12:00 AM
 * Sun/Sat open extra from 12:00 AM - 01:00 AM
 */
$storeSchedule = [
    'Sun' => ['12:00 AM' => '01:00 AM', '09:00 AM' => '12:00 AM'],
    'Mon' => ['09:00 AM' => '12:00 AM'],
    'Tue' => ['09:00 AM' => '12:00 AM'],
    'Wed' => ['09:00 AM' => '12:00 AM'],
    'Thu' => ['09:00 AM' => '12:00 AM'],
    'Fri' => ['09:00 AM' => '12:00 AM'],
    'Sat' => ['12:00 AM' => '01:00 AM', '09:00 AM' => '12:00 AM']
];

然后循环显示当前时间范围,并检查当前时间或提供的时间戳是否在一个范围内。您可以使用DateTime类为每个时间范围的开始/结束时间生成 DateTime 对象。

以下内容将允许您指定时间戳,以防您想要检查提供的时间戳而不是当前时间。

// current or user supplied UNIX timestamp
$timestamp = time();

// default status
$status = 'closed';

// get current time object
$currentTime = (new DateTime())->setTimestamp($timestamp);

// loop through time ranges for current day
foreach ($storeSchedule[date('D', $timestamp)] as $startTime => $endTime) {

    // create time objects from start/end times
    $startTime = DateTime::createFromFormat('h:i A', $startTime);
    $endTime   = DateTime::createFromFormat('h:i A', $endTime);

    // check if current time is within a range
    if (($startTime < $currentTime) && ($currentTime < $endTime)) {
        $status = 'open';
        break;
    }
}

echo "We are currently: $status";

请参阅上面的DEMO

答案 1 :(得分:3)

根据已接受的答案修改,以便在我们的商店营业时间实际为EST的AWS Debian服务器(位于西海岸)上使用...也被放入PHP函数中。

/*
 * decide based upon current EST if the store is open
 *
 * @return bool
 */
function storeIsOpen() {
    $status = FALSE;
    $storeSchedule = [
        'Mon' => ['08:00 AM' => '05:00 PM'],
        'Tue' => ['08:00 AM' => '05:00 PM'],
        'Wed' => ['08:00 AM' => '05:00 PM'],
        'Thu' => ['08:00 AM' => '05:00 PM'],
        'Fri' => ['08:00 AM' => '05:00 PM']
    ];

    //get current East Coast US time
    $timeObject = new DateTime('America/New_York');
    $timestamp = $timeObject->getTimeStamp();
    $currentTime = $timeObject->setTimestamp($timestamp)->format('H:i A');

    // loop through time ranges for current day
    foreach ($storeSchedule[date('D', $timestamp)] as $startTime => $endTime) {

        // create time objects from start/end times and format as string (24hr AM/PM)
        $startTime = DateTime::createFromFormat('h:i A', $startTime)->format('H:i A');
        $endTime = DateTime::createFromFormat('h:i A', $endTime)->format('H:i A');

        // check if current time is within the range
        if (($startTime < $currentTime) && ($currentTime < $endTime)) {
            $status = TRUE;
            break;
        }
    }
    return $status;
}

答案 2 :(得分:2)

如果您在午夜后保持营业,那么您应该重新组合阵列中的所有开放时间,因为昨天的开放时间可能会有影响。也有可能每天有几个开放时间可能很方便。

<?php

$times = array(
    'mon' => '9:00 AM - 12:00 AM',
    'tue' => '9:00 AM - 12:00 AM',
    'wed' => '9:00 AM - 12:00 AM',
    'thu' => '9:00 AM - 12:00 AM',
    'fri' => '9:00 AM - 1:00 AM',
    'sat' => '9:00 AM - 1:00 PM, 2:00 PM - 1:00 AM',
    'sun' => 'closed'
);

function compileHours($times, $timestamp) {
    $times = $times[strtolower(date('D',$timestamp))];
    if(!strpos($times, '-')) return array();
    $hours = explode(",", $times);
    $hours = array_map('explode', array_pad(array(),count($hours),'-'), $hours);
    $hours = array_map('array_map', array_pad(array(),count($hours),'strtotime'), $hours, array_pad(array(),count($hours),array_pad(array(),2,$timestamp)));
    end($hours);
    if ($hours[key($hours)][0] > $hours[key($hours)][1]) $hours[key($hours)][1] = strtotime('+1 day', $hours[key($hours)][1]);
    return $hours;
}

function isOpen($now, $times) {
    $open = 0; // time until closing in seconds or 0 if closed
    // merge opening hours of today and the day before
    $hours = array_merge(compileHours($times, strtotime('yesterday',$now)),compileHours($times, $now)); 

    foreach ($hours as $h) {
        if ($now >= $h[0] and $now < $h[1]) {
            $open = $h[1] - $now;
            return $open;
        } 
    }
    return $open;
}

$now = strtotime('7:59pm');
$open = isOpen($now, $times);

if ($open == 0) {
    echo "Is closed";
} else {
    echo "Is open. Will close in ".ceil($open/60)." minutes";
}

?>

另一方面,如果您只想解决9am - 5am时间问题,则应检查是否$from > $to并在必要时向$to添加1天。

答案 3 :(得分:0)

我建议使用PHP的DateTime类。它的开发是为了解决所有这些问题,为这些难以完成的任务提供了一个简单的界面。

答案 4 :(得分:0)

也许这个?我发现它here并略微调整了一下。

    <?php
    date_default_timezone_set('Europe/Stockholm'); // timezone 
    $today = date(N); // today ex. 6

    //Opening hours
    $opening_hours[1] = "12:00"; $closing_hours[1] = "00:00";
    $opening_hours[2] = "12:00"; $closing_hours[2] = "00:00";
    $opening_hours[3] = "12:00"; $closing_hours[3] = "00:00";
    $opening_hours[4] = "12:00"; $closing_hours[4] = "02:00";
    $opening_hours[5] = "12:00"; $closing_hours[5] = "04:00";
    $opening_hours[6] = "13:00"; $closing_hours[6] = "04:00";
    $opening_hours[7] = "13:00"; $closing_hours[7] = "00:00";

    // correction for opening hours after midnight.
    if(intval($closing_hours[$today - 1]) > 0)
        $today = date(N,strtotime("-".intval($closing_hours[$today - 1])." hours"));

    // now check if the current time is after openingstime AND smaller than closing hours of tomorrow
            if (

    (date("H:i") > $opening_hours[$today] && 
    ((date("Y-m-d H:i") < date("Y-m-d H:i", strtotime('tomorrow +'.intval($closing_hours[$today]).' hours')))) 
    ) ||
    date("H:i") < $closing_hours[$today] && 
    ((date("Y-m-d H:i") < date("Y-m-d H:i", strtotime('today +'.intval($opening_hours[$today]).' hours'))))

    )  {
        $label = "label-success";   
        $label_text = "OPEN";
        $label_time = $closing_hours[$today];
    } else {
        $label = "label-danger";
        $label_text = "GESLOTEN";
        $label_time = $opening_hours[$today];
    }
    ?>

答案 5 :(得分:0)

我尝试了几天不同的代码,并发现这对我来说是一个解决方案。发布它,以防它可能帮助他人。将时间从AM / PM格式转换回UNIX时非常重要。

我使用从数据库中提取的时间,因此您必须定义$startTime$endTime

//  define each days time like so
$monsta = "07:00 AM";
$monend = "05:00 PM";

$storeSchedule = [
    'Mon' => ["$monsta" => "$monend"],
    'Tue' => ["$tuessta" => "$tuesend"],
    'Wed' => ["$wedssta" => "$wedsend"],
    'Thu' => ["$thurssta" => "$thursend"],
    'Fri' => ["$frista" => "$friend"],
    'Sat' => ["$satsta" => "$satend"],
    'Sun' => ["$sunsta" => "$sunend"]
];

// default time zone
$timestamp = time() - 18000; 

// default status
$status = 'Closed';

// loop through time ranges for current day
foreach ($storeSchedule[date('D', $timestamp)] as $startTime => $endTime) {

// create time objects from start/end times
$startTime = strtotime($startTime);
$endTime = strtotime($endTime);

// check if current time is within a range
if ($startTime <= $timestamp && $timestamp <= $endTime ) {
    $status = 'Open';

    }
}   

echo '<p><b>Today\'s Hours</b><br />'.$days[$d].'<br />';
echo "<b>We are currently: $status </b></p>";

答案 6 :(得分:0)

有点晚了,但我有其他人的解决方案,如果这里的人不太适合他们的需要。我确实喜欢在午夜之后关闭几天的多个时间集的解决方案但是这会增加额外的数据处理以显示小时数。您首先必须检查是否有多个时间集可用,然后确认它们已连接(两者之间没有时间)。

我的解决方案是编写一个函数,通过开放时间,结束时间和时间问题,对于open,它将返回true,关闭时返回false:

function is_open($open, $close, $query_time){
    $open = new DateTime($open);
    $close = new DateTime($close);
    $query_time = new DateTime($query_time);
    $is_open = false;
    //Determine if open time is before close time in a 24 hour period
    if($open < $close){
        //If so, if the query time is between open and closed, it is open
        if($query_time > $open){
            if($query_time < $close){
                $is_open = true;
            }
        }
    }
    elseif($open > $close){
        $is_open = true;
        //If not, if the query time is between close and open, it is closed
        if($query_time < $open){
            if($query_time > $close){
                $is_open = false;
            }
        }
    }
    return $is_open;
}