Query date in wordpress loop

The question:

I currently have a custom post type called ‘events’. I created this from a tutorial here http://tatiyants.com/how-to-use-wordpress-custom-post-types-to-add-events-to-your-site/. I want to query the date to only show the posts with dates coming up and not ones on the past. $event_date >= time

However in the tutorial he displays the results using a shortcode. I am trying to convert this to a standard wp loop so I can display it in my index.php. He uses the following within his shortcode function:

add_shortcode( 'events', 'get_events_shortcode' );

function get_events_shortcode($atts){
    global $post;

    // get shortcode parameter for daterange (can be "current" or "past")
    extract( shortcode_atts( array(
        'daterange' => 'current',
    ), $atts ) );

    ob_start();

    // prepare to get a list of events sorted by the event date
    $args = array(
        'post_type' => 'events',
        'orderby'   => 'event_date',
        'meta_key'  => 'event_date',
        'order'     => 'ASC'
    );

    query_posts( $args );

    $events_found = false;

    // build up the HTML from the retrieved list of events
    if ( have_posts() ) {
        while ( have_posts() ) {
            the_post();
            $event_date = get_post_meta($post->ID, 'event_date', true);

            switch ($daterange) {
                case "current":
                    if ($event_date >= time() ) {
                        echo get_event_container();
                        $events_found = true;
                    }
                    break;

                case "past":
                    if ($event_date < time() ) {
                        echo get_past_event_summary();
                        $events_found = true;
                    }
                    break;
            }
        }
    }

    wp_reset_query();

    if (!$events_found) {
        echo "<p>no events found.</p>";
    }

    $output_string = ob_get_contents();
    ob_end_clean();

    return $output_string;
}

Any help or direction will be greatly appreciated as though I have programmed themes before this is causing me a headache.

The Solutions:

Below are the methods you can try. The first solution is probably the best. Try others if the first one doesn’t work. Senior developers aren’t just copying/pasting – they read the methods carefully & apply them wisely to each case.

Method 1

You want to query for posts with event_date in the future but you have saved (or so it seems from a comment), your dates as:

date("F", $unixtime)." ".date("d", $unixtime).", ".date("Y", $unixtime);

That is “textual month name” + “numeric day” + “numeric year”. There is no way to query/sort that format so that it matches a calendar. Your sorting options are “alphabetical”, which is obviously going to be wrong, or “numerical”, which is also obviously wrong. The only human readable date format that sorts in a way that matches a calendar is “numeric year” + “numeric month” + “numeric day”, or “YYYY-MM-DD”. The choice of separator is arbitrary and can be nothing. That is date('Y-m-d'). If your dates were stored in a rational format a query like the following should do what you need:

$args = array(
    'post_type' => 'events',
    'orderby'   => 'event_date',
    'meta_key'  => 'event_date',
    'order'     => 'ASC',
    'meta_query' => array(
      array(
        'key' => 'event_date',
        'value' => date('Y-m-d',time()),
        'compare' => '>'
      )
    ),
);
$q = new WP_Query($args);
var_dump($q->request);

You can always just store a Unix timestamp as well. Those sort matching calendar order as well. You would then format the date on display. This is my preference with dates unless you are saving to “date” format column in a MySQL table. If you save as a timestamp, use:

'value' => strtotime('today'),

instead of:

'value' => date('Y-m-d',time()),

Method 2

This will query / show all future posts – standard WP Query surrounded by 2 filters, 1 to add the filter so it applies to this query and another to remove it so it doesn’t apply to any other queries:

This would be the query for your custom loop:

add_filter( 'posts_where', 'filter_where' );
$events = new WP_Query(array('post_type' => 'post', 'posts_per_page' => -1, 'order' => 'ASC', 'orderby' => 'date', 'post_status' => array('publish', 'future')));
remove_filter( 'posts_where', 'filter_where' );

Add this to your functions file for the filter:

function filter_where( $where = '' ) {
    global $wpdb;
    $where .= " AND ($wpdb->postmeta.meta_key = 'event_date' AND $wpdb->postmeta.meta_value >= '".date('Y-m-d')."')";
    return $where;
}

These 2 combined will query all posts on todays days and after, then order them by date. Is this what you’re referring to?


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Comment