21

如果时间是上午到下午(例如:上午 11 点 - 晚上 10 点),我的代码可以正常工作,但如果营业时间是上午到上午(例如:上午 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
}
4

8 回答 8

48

您首先需要创建一个数组来保存您的星期几,以及它们各自的收盘/开盘时间范围。

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

于 2013-02-18T02:59:28.830 回答
6

从接受的答案修改为在我们的商店营业时间实际上是 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;
}
于 2016-12-06T18:34:33.060 回答
3

您应该将所有营业时间重新组合成一个数组,因为如果您在午夜之后继续营业,昨天的营业时间可能会产生影响。也有可能每天有几个开放时间可能很方便。

<?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添加 1 天。$to

于 2013-11-24T13:11:09.217 回答
1

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

我的解决方案是编写一个函数,传递打开时间、关闭时间和有问题的时间,它将返回 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;
}
于 2017-08-29T17:28:09.267 回答
0

也许这个?我在这里找到了它并对其进行了一些调整。

    <?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];
    }
    ?>
于 2016-02-27T17:13:35.567 回答
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>";
于 2016-11-29T19:44:22.257 回答
0

这是我的版本,因为 12 小时时间格式不适合我。请注意 $pancits[] 来自我的数据库

$status = 'Closed';
// get current time object
$timestamp = time();
// $currentTime = (new DateTime())->setTimestamp($timestamp);
$currentTime = date('H:i');

$startTime = date('H:i', strtotime($pancits['p_oTime']));
$endTime   = date('H:i', strtotime($pancits['p_cTime']));

if (($startTime <= $currentTime) && ($currentTime <= $endTime)) {
    $status = 'Open';
    //echo $status;
}

echo "<b>Currently $status</b>";

echo '
    <p><b>Time Open: </b>'.date('h:ia', strtotime($pancits['p_oTime'])).'</p>
    <p><b>Time Close: </b>'.date('h:ia', strtotime($pancits['p_cTime'])).'</p>
';
于 2018-09-14T07:44:02.803 回答
-1

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

于 2013-02-16T00:15:07.403 回答