Determine If Business Is Open/Closed Based On Business Hours

Stephen picture Stephen · Feb 16, 2013 · Viewed 23.4k times · Source

My code works fine if the times are AM to PM (Ex: 11 AM - 10 PM), but if the locations hours of operation are AM to AM (Ex: 9 AM - 1 AM) it breaks. Here is my code:

$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
}

Answer

cryptic ツ picture cryptic ツ · Feb 18, 2013

You would first need to create an array which will hold your days of the week, and their respective close/open time range(s).

/**
 * 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']
];

You then loop over the current day's time range(s) and check to see if the current time or supplied timestamp is within a range. You do this by using the DateTime class to generate a DateTime object for each time range's start/end time.

The below will do this and allow you to specify a timestamp in case you are wanting to check a supplied timestamp instead of the current time.

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

See DEMO of above