General * - Date Format: Must use dd/mm/yyyy format (e.g., 31/12/2025) * - Accepts an optional `end_text` to show when the timer countdown is finished. * - Accepts an optional `time` (in 24 hour format) attribute to configure what time of day. Useful * for offsetting against timezones. Can be HH:MM or HH:MM:SS format. * * USAGE: * [countdown date="31/12/2025"] [countdown date="01/01/2026"] * * NOTES: * Supports multiple timers on same page via static counter Countdown stops at zero (doesn't go * negative) Uses site timezone from WordPress settings JavaScript updates every second Timer * starts automatically on page load Falls back gracefully with error messages for invalid dates */ add_shortcode( 'countdown', function ( $atts ) { static $count = 0; ++$count; // Register script handle once static $script_enqueued = false; if ( ! $script_enqueued ) { wp_register_script( 'bld-countdown-timer', '', [], false, true ); // phpcs:ignore WordPress.WP.EnqueuedResourceParameters.NoExplicitVersion wp_enqueue_script( 'bld-countdown-timer' ); $script_enqueued = true; } $atts = shortcode_atts( [ 'date' => '', // expects dd/mm/yyyy, 'end_text' => '', 'time' => '00:00:00', // expects HH:MM:SS or HH:MM in 24-hour format ], $atts, 'countdown' ); if ( empty( $atts['date'] ) ) { return '

Countdown date not set.

'; } // Convert dd/mm/yyyy to yyyy-mm-dd $parts = explode( '/', $atts['date'] ); if ( count( $parts ) !== 3 ) { return '

Invalid date format. Use dd/mm/yyyy.

'; } list($day, $month, $year) = $parts; if ( ! checkdate( $month, $day, $year ) ) { return '

Invalid date. Make sure the day, month, and year are valid.

'; } $time = sanitize_text_field( $atts['time'] ); // Validate time format (HH:MM or HH:MM:SS) if ( ! preg_match( '/^([01]?[0-9]|2[0-3]):[0-5][0-9](:[0-5][0-9])?$/', $time ) ) { return '

Invalid time format. Use HH:MM or HH:MM:SS.

'; } try { $target_datetime = new DateTime( "$year-$month-$day $time", wp_timezone() ); } catch ( Exception $e ) { return '

Invalid timezone or date. Please check site settings.

'; } $iso8601_date = $target_datetime->format( DateTimeInterface::ATOM ); // ISO 8601 format with timezone $timer_id = 'countdown-timer-' . $count; $end_text = ! empty( $atts['end_text'] ) ? wp_kses_post( $atts['end_text'] ) : ''; ob_start(); ?>
0
Days
0
Hours
0
Minutes
0
Seconds