25% off ProSNIPC25OFF

Business Hours Table With Open/Closed

Shortcode that renders a weekly hours table and shows a live "Open now" or "Closed" badge based on the visitor's local time.

Module2 parts · by SnipCraft

PHPLogic

php
<?php
if ( ! function_exists( 'scseed_hours_shortcode' ) ) :

add_shortcode( 'scseed_hours', 'scseed_hours_shortcode' );
function scseed_hours_shortcode( $atts ) {
    $atts = shortcode_atts( array(
        'timezone' => get_option( 'timezone_string', 'UTC' ),
        'closed'   => 'Sunday',
    ), $atts, 'scseed_hours' );

    // Schedule: day => [open, close] in H:i (24-hour). Customise via filter.
    $schedule = apply_filters( 'scseed_hours_schedule', array(
        'Monday'    => array( '09:00', '17:00' ),
        'Tuesday'   => array( '09:00', '17:00' ),
        'Wednesday' => array( '09:00', '17:00' ),
        'Thursday'  => array( '09:00', '17:00' ),
        'Friday'    => array( '09:00', '16:00' ),
        'Saturday'  => array( '10:00', '14:00' ),
        'Sunday'    => null,  // null = closed
    ) );

    $tz        = sanitize_text_field( $atts['timezone'] );
    $tz_obj    = timezone_open( $tz ) ?: new DateTimeZone( 'UTC' );
    $now       = new DateTime( 'now', $tz_obj );
    $day_name  = $now->format( 'l' );
    $now_mins  = intval( $now->format( 'H' ) ) * 60 + intval( $now->format( 'i' ) );
    $is_open   = false;

    if ( isset( $schedule[ $day_name ] ) && is_array( $schedule[ $day_name ] ) ) {
        list( $open_str, $close_str ) = $schedule[ $day_name ];
        list( $oh, $om ) = explode( ':', $open_str );
        list( $ch, $cm ) = explode( ':', $close_str );
        $open_mins  = intval( $oh ) * 60 + intval( $om );
        $close_mins = intval( $ch ) * 60 + intval( $cm );
        $is_open    = ( $now_mins >= $open_mins && $now_mins < $close_mins );
    }

    ob_start();
    ?>
    <div class="scseed-hours">
        <div class="scseed-hours__badge scseed-hours__badge--<?php echo $is_open ? 'open' : 'closed'; ?>">
            <?php echo $is_open ? 'Open now' : 'Closed now'; ?>
        </div>
        <table class="scseed-hours__table">
            <caption class="scseed-hours__caption">Business Hours (<?php echo esc_html( $tz ); ?>)</caption>
            <tbody>
            <?php foreach ( $schedule as $day => $hours ) : ?>
                <tr class="scseed-hours__row<?php echo $day === $day_name ? ' is-today' : ''; ?>">
                    <th class="scseed-hours__day" scope="row"><?php echo esc_html( $day ); ?></th>
                    <td class="scseed-hours__time">
                        <?php if ( is_array( $hours ) ) : ?>
                            <?php echo esc_html( $hours[0] . ' – ' . $hours[1] ); ?>
                        <?php else : ?>
                            <span class="scseed-hours__closed">Closed</span>
                        <?php endif; ?>
                    </td>
                </tr>
            <?php endforeach; ?>
            </tbody>
        </table>
    </div>
    <?php
    return ob_get_clean();
}
endif;

CSSStyles

css
.scseed-hours { max-width: 400px; font-family: inherit; }
.scseed-hours__badge {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.35rem 0.85rem;
    border-radius: 50px;
    font-weight: 700;
    font-size: 0.85rem;
    margin-bottom: 1rem;
}
.scseed-hours__badge::before {
    content: '';
    display: inline-block;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: currentColor;
}
.scseed-hours__badge--open   { background: #d4edda; color: #155724; }
.scseed-hours__badge--closed { background: #f8d7da; color: #721c24; }
.scseed-hours__table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.92rem;
}
.scseed-hours__caption {
    text-align: left;
    font-weight: 700;
    margin-bottom: 0.5rem;
    caption-side: top;
    padding-bottom: 0.5rem;
    font-size: 0.88rem;
    color: #888;
}
.scseed-hours__row { border-bottom: 1px solid #eee; }
.scseed-hours__row.is-today { background: #f0f7ff; font-weight: 700; }
.scseed-hours__day, .scseed-hours__time {
    padding: 0.55rem 0.5rem;
    text-align: left;
    vertical-align: middle;
}
.scseed-hours__day { width: 45%; color: #444; }
.scseed-hours__closed { color: #999; font-style: italic; }
#shortcode#contact#business-hours#schedule#local