38

I have a query_posts call in a WP template. Through the use of the More Fields Plugin I can give the site admin the ability to create an event (custom post type) and then enter a date which is formatted: YYYY/mm/dd.

The main question is; what value should I pass to the value option in the meta_query array? I am currently trying to pass "date("Y/m/d h:i A")" (minus the quotes), because, as I understand it, that will print the current date today. I don't care about the time of date so that may be irrelevant. Ulitimatly I am trying to use the compare option to nail down showing upcoming events, past events in different places on this site. In one other spot I actually need to pass the value option an array that prints that first and last day of the current month, limiting the output to events happening this month.

<?php 
            query_posts( array( 
              'post_type'  => 'event',        // only query events
              'meta_key'    => 'event_date',  // load up the event_date meta
              'orderby'     => 'meta_value',  // sort by the event_date
              'order'       => 'asc',         // ascending, so earlier events first
              'posts_per_page' => '2',
              'meta_query'  => array(         // restrict posts based on meta values
                  'key'     => 'event_date',  // which meta to query
                  'value'   => date("Y/m/d h:i A"),  // value for comparison
                  'compare' => '>=',          // method of comparison
                  'type'    => 'DATE'         // datatype, we don't want to compare the string values
                ) // end meta_query array
              ) // end array
            ); // close query_posts call
                 ?>

4 Answers 4

52

I wound up working on the exact same thing and this post was very helpful. I used Custom Fields and here is the code that I used to create a list of all events greater than the current date. Note the extra taxonomy based filters.

<?php // Let's get the data we need to loop through below

$events = new WP_Query( 
    array(
        'post_type' => 'event', // Tell WordPress which post type we want
        'orderby' => 'meta_value', // We want to organize the events by date    
        'meta_key' => 'event-start-date', // Grab the "start date" field created via "More Fields" plugin (stored in YYYY-MM-DD format)
        'order' => 'ASC', // ASC is the other option    
        'posts_per_page' => '-1', // Let's show them all.   
        'meta_query' => array( // WordPress has all the results, now, return only the events after today's date
            array(
                'key' => 'event-start-date', // Check the start date field
                'value' => date("Y-m-d"), // Set today's date (note the similar format)
                'compare' => '>=', // Return the ones greater than today's date
                'type' => 'DATE' // Let WordPress know we're working with date
                )
            ),
        'tax_query' => array( // Return only concerts (event-types) and events where "songs-of-ascent" is performing
            array(
                'taxonomy' => 'event-types',
                'field' => 'slug',
                'terms' => 'concert',
                ),
            array(
                'taxonomy' => 'speakers',
                'field' => 'slug',
                'terms' => 'songs-of-ascent',
                )
            )
        )
    );
?>
4
  • 5
    why not 'type' => 'DATE' ? Feb 23, 2015 at 23:18
  • I can confirm the doubts of @FranciscoCorralesMorales: you have to specify 'DATE' type, especially because date meta fields aren't saved as number but in the form of "Y-m-d" (please note hyphens). I've edited Jonathan's answer. Feb 17, 2017 at 13:39
  • For internationalization, you might want to use the WordPress function date_i18n(), instead of the php native date().
    – Jake
    Sep 1, 2017 at 22:02
  • I think it would be helpful to specify the format of how you are storing event dates in your Custom Field since comparing date formats seems to be the critical piece in setting up a functional meta query. Feb 17 at 2:11
7

It largely depends on how your date is stored in the meta value in the first place. In general, it is a good idea to store dates in MySQL as MySQL dates/timestamps.

MySQL timestamps have the format Y-m-d h:i:s.

However, it is always a good idea to use WP's own date mangling functions. As such, to get the current date in MySQL format, use current_time('mysql').

To format a MySQL date for display, use mysql2date($format, $mysql_date). In this case it is best to display the date as configured in the settings, so use $format = get_option('date_format');.

To store a user-selected date, you'll have to transcode it into a MySQL date. To do so, the easiest - but not safest - way is date('Y-m-d h:i:s', $unix_timestamp);. $unix_timestamp can often be derived via strtotime($user_input).

However, strtotime() doesn't do sanity checks on it's own, so it's best to write your own converstion function.

As for getting the month range, here's a function i'm using to get the month boundaries for any MySQL timestamp:

function get_monthrange($time) {
    $ym = date("Y-m", strtotime($time));
    $start = $ym."-01";
    $ym = explode("-", $ym);
    if ($ym[1] == 12) {
        $ym[0]++; $ym[1] = 1;
    } else {
        $ym[1]++;
    }
    $d = mktime( 0, 0, 0, $ym[1], 1, $ym[0] );
    $d -= 86400;
    $end = date("Y-m-d", $d);
    return array( $start, $end );
}

If you want to get the week boundaries, WP already comes with a function for that: get_weekstartend($time);, which also delivers the boundaries as an array.

You can then use these in your meta_query argument by doing two separate comparisons.

1
  • Don't you mean "MySQL timestamps have the format Y-m-d G:i:s"? G:i:s is 24-hour, h:i:s is 12-hour.
    – admcfajn
    Aug 11, 2018 at 1:27
3

I wound up going with the following. I setup a event-momth field and comparing from there. thanks for the help

<?php 
        $event_query = new WP_Query(
        array( 
          'post_type'   => 'event',        // only query events
          'meta_key'    => 'event-month',  // load up the event_date meta
          'order_by'        => 'event_date',
          'order'       => 'asc',         // ascending, so earlier events first
          'meta_query'  => array(
             array(         // restrict posts based on meta values
              'key'     => 'event-month',  // which meta to query
              'value'   => date("n"),  // value for comparison
              'compare' => '=',          // method of comparison
              'type'    => 'NUMERIC'         // datatype, we don't want to compare the string values
            ) // meta_query is an array of query ites
           ) // end meta_query array
          ) // end array
        ); // close WP_Query constructor call

 ?>
   <?php while($event_query->have_posts()): $event_query->the_post(); //loop for events ?>
2

Hi below I am posting my solution. Where I have stored date in Y-m-d H:i format (like 2013-07-31 16:45).

  • Sorted according to Event start date.
  • Event which ending after Today will be queried only by meta_query.

    date_default_timezone_set('Asia/Calcutta');

I set default time zone for date() function.

$args = array(
    'posts_per_page'  => 3,
    'orderby'         => 'meta_value',
    'meta_key'    => 'event_start_date_time',
    'order'           => 'ASC',
    'post_type'       => 'events',
    'meta_query' => array(
      array(
        'key' => 'event_end_date_time',
        'value' => date("Y-m-d H:i"),
        'compare' => '>=',
        'type' => 'DATE'
        )
      )
    ); 
query_posts( $args );

if( have_posts() ) : while ( have_posts() ) : the_post();

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.