Earlier today, a patch for WordPress that I’ve been working on got committed to WordPress trunk. “Trunk” is the in-development version of WordPress and will eventually become the next version of WordPress, in this case 3.7.

My patch introduces the ability to do complex date-based queries for fetching both posts and comments from the WordPress database. In the past, you could select posts that had a specific value for year, month, etc. but there was no way to do things like selecting all posts before (or after) a certain date or selecting all posts between two different dates. With my patch, this and more is now easily possible.

Here’s some examples:

// Get the 10 most recent posts made // between 9AM and 5PM on weekdays $some_posts = new WP_Query( array( 'date_query' => array( array( 'hour' => 9, 'compare' => '>=', ), array( 'hour' => 17, 'compare' => '<=', ), array( 'dayofweek' => array( 2, 6 ), 'compare' => 'BETWEEN', ), ), 'posts_per_page' => 10, ) ); // Get all posts from this summer // June 1st to August 31st, inclusive // Note that strtotime()-compatible strings can be used $some_posts = new WP_Query( array( 'date_query' => array( array( // String via strtotime() 'after' => 'June 1st, 2013', // Or if you want, an array 'before' => array( 'year' => 2013, 'month' => 8, 'day' => 31, ), 'inclusive' => true, ), ), 'posts_per_page' => -1, ) ); // Any posts made over a year ago // but modified in the past month $some_posts = new WP_Query( array( 'date_query' => array( array( 'column' => 'post_date_gmt', 'before' => '1 year ago', ), array( 'column' => 'post_modified_gmt', 'after' => '1 month ago', ) ), 'posts_per_page' => -1, ) );

It works for comments too:

// All comments from post ID 123 // that are within the past week $some_comments = get_comments( array( 'post_ID' => 123, 'date_query' => array( array( 'after' => '1 week ago', ), ), ) );

As you can see, the possibilities and combinations of cool things you can do are endless.

Here’s all of the possible arguments:

'date_query' => array( 'column' => 'optional, column to query against, default is post_date', 'compare' => 'optional, see WP_Date_Query::get_compare()', 'relation' => 'optional, OR or AND, how the sub-arrays should be compared, default is AND', array( 'column' => 'see above', 'compare' => 'see above', 'after' => 'string or array, see WP_Date_Query::build_mysql_datetime()', 'before' => 'string or array, see WP_Date_Query::build_mysql_datetime()', 'inclusive' => 'boolean, for after/before, whether exact value should be matched or not', 'year' => '4 digit int', 'month' => 'int, 1-12', 'week' => 'int, 0-53', 'day' => 'int, 1-31', 'hour' => 'int, 0-23', 'minute' => 'int, 0-60', 'second' => 'int, 0-60', ), array( ... ), .. ),

Additionally, all of the old-school date and time arguments for WP_Query are now handled by my code as well. They will continue to work as before and you only need to use the date_query parameter if you want more advanced control of your results.

Questions? Anything you want me to clarify? Leave a comment below. 🙂