Date Queries In WordPress 3.7+

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:

[code lang=”php”]// 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,
) );[/code]

It works for comments too:

[code lang=”php”]// 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’,
),
),
) );[/code]

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

Here’s all of the possible arguments:

[code lang=”php”]’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(

),
..
),[/code]

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. 🙂