Smart ACF Start & End Date Shortcode

Managing event dates with both start and end dates can get messy fast. Do you show both dates? Just one? What about times? This shortcode analyzes your ACF start and end date fields and automatically outputs the smartest format based on what’s available. It works for any content type with start and end dates, not just events. Use it for project timelines, schedules, rental bookings, etc.

The Setup

You’ll need to create three ACF fields:

  • event_start (Date Time Picker field) – Required
  • event_end (Date Time Picker field) – Optional
  • event_all_day (True/False field) – Optional

How it Works

This shortcode intelligently formats the output based on what data is available in your ACF fields:

  • Single date, all-day: “Mar 15, 2024”
  • Single date with time: “Mar 15, 2024 2:00pm – 5:00pm”
  • Multi-day, all-day: “Mar 15, 2024 – Mar 17, 2024”
  • Multi-day with times: “Mar 15, 2024 2:00pm – Mar 17, 2024 5:00pm”

If there’s no end date, it only shows the start. Same start and end date? It shows a time range instead of repeating the date. Different dates? It displays the full range. The shortcode handles all the logic so you get clean, readable output every time.

On to the Code!

Add this code to your child theme’s functions.php file or a code snippets plugin.

Usage: Display the current post’s event date using [event_date]

PHP
add_shortcode('event_date', function($atts) {
    if (!function_exists('get_field')) {
        return '';
    }
    
    $atts = shortcode_atts(array(
        'post_id' => get_the_ID()
    ), $atts);
    
    $start_date = get_field('event_start', $atts['post_id']);
    $end_date = get_field('event_end', $atts['post_id']);
    $all_day = get_field('event_all_day', $atts['post_id']);
    
    if (!$start_date) {
        return '';
    }
    
    $start_timestamp = strtotime($start_date);
    $end_timestamp = $end_date ? strtotime($end_date) : null;
    
    // Format start date
    $start_date_formatted = date('M j, Y', $start_timestamp);
    $output = $start_date_formatted;
    
    // Add time if not all-day event
    if (!$all_day) {
        $start_time = date('g:ia', $start_timestamp);
        $output .= ' ' . $start_time;
    }
    
    // Add end date/time if present
    if ($end_timestamp) {
        $end_date_formatted = date('M j, Y', $end_timestamp);
        
        // Same date - show time range or just date for all-day
        if ($start_date_formatted === $end_date_formatted) {
            if (!$all_day) {
                $end_time = date('g:ia', $end_timestamp);
                $output = $start_date_formatted . ' ' . $start_time . ' - ' . $end_time;
            }
            // If all-day and same date, just show single date (already in $output)
        } else {
            // Different dates
            if (!$all_day) {
                $end_time = date('g:ia', $end_timestamp);
                $output .= ' - ' . $end_date_formatted . ' ' . $end_time;
            } else {
                // All-day, different dates - show date range
                $output .= ' - ' . $end_date_formatted;
            }
        }
    }
    
    return $output;
});

Found this
Snippet
useful?

Consider buying me a coffee!  ☕️  Your support helps me create more free snippets for the WordPress community.