web-dev-qa-db-ja.com

営業時間に基づいて営業しているかどうかを判断する

時刻がAMからPM(例:午前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
}
13
Stephen

最初に、曜日とそれぞれのクローズ/オープン時間範囲を保持する配列を作成する必要があります。

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

上記の [〜#〜]デモ[〜#〜] を参照してください

38
cryptic ツ

営業時間が実際にESTであるAWSDebianサーバー(西海岸にある)で使用するために受け入れられた回答から変更されました...また、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;
}
4
sdforet

深夜以降も営業している場合は、昨日の営業時間が影響する可能性があるため、すべての営業時間を配列に再グループ化する必要があります。また、1日に数時間営業する可能性があると便利かもしれません。

<?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日を追加する必要があります。

2
Daniel P

少し遅れましたが、ここにいる人が彼らのニーズに完全に合わない場合、私は他の人のための解決策を持っています。深夜以降に終了する日に複数の時間セットを設定するソリューションが好きですが、これにより、時間を表示するためのデータ処理が追加されます。最初に、使用可能な時間セットが複数あるかどうかを確認してから、それらが接続されていることを確認する必要があります(間に時間はありません)。

私の解決策は、代わりに、開始時間、終了時間、および問題の時間を渡す関数を作成することでした。この関数は、開いている場合は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;
}
1
Xandor

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>
';
0
Dakila Lozano

PHPの DateTime クラスを利用することをお勧めします。このようなタスクを実行するのが難しいためのシンプルなインターフェイスを提供することにより、これらすべての問題を解決するために開発されました。

0
FtDRbwLXw6

多分これ?私はそれを見つけました ここ そしてそれを少し微調整しました。

    <?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];
    }
    ?>
0
RA MEDIA

私はこのコードをいくつかの異なる方法で1日試しましたが、これが私にとっての解決策であることがわかりました。他の人に役立つかもしれない場合に備えて投稿してください。時刻を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>";
0
Marty Demichele