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