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. 🙂
Pingback: How to list most commented posts with the new date queries in WordPress 3.7+ | Daniele Milana
Hi. I’ve just started playing with WordPress development and I was looking for a way to get comments according to a specific week. Your code is very useful, thanks for that. But a question, how come this is nowhere in the WordPress documentation?
The WordPress Codex is a wiki which anyone can edit and sometimes lags behind the actual code (and it’s inline documentation). My code has been documented for post queries:
http://codex.wordpress.org/Function_Reference/WP_Query#Date_Parameters
But yes, someone needs to add it here too:
http://codex.wordpress.org/Class_Reference/WP_Comment_Query
http://codex.wordpress.org/Function_Reference/get_comments
Alright, thanks for that.
I use an app (Dash) for the documentation, I wasn’t fully aware that anyone could edit the doc. I just assumed it was up to date.
How to query posts by dynamically selecting dates using jquery datepicker?
You would need custom code or a plugin for that to be the interface between jQuery Datepicker and the actual database query.
Which plugins is best? Any suggestions? My plan is to filtering the archives between two dates based on jquary datepicker with “from” and “to” values instead of monthly/quarterly/yearly archives.
I’m not aware of any plugins that do this but I’m sure some exist. Search the plugin repository and I’ll bet you find some.
I need a date query to return posts published between X days prior to post date of current post, and the post date of current post (excluding current post).
Requires a static date range because this is for an email newsletter template. Newsletter will be sent weekly, as a digest of previous week’s posts, and will also be archived as a post, so it must retain correct posts for its’ week.
That’s pretty simple to do. Here’s some completely untested code that will likely work:
Thank you for the rapid reply; code works well. I had trouble figuring out the $after_date variable… but your suggestion is spot-on, Mr. Mills.
Hello Alex, I tried to get posts between 2009 and 2010 inclusive the years. So I would expect all posts from 1st January 2009 to 31st December 2010.
So the ‘date_query’ parameter is:
array(1) {
[0]=>
array(3) {
[“after”]=>
array(1) {
[“year”]=>
int(2009)
}
[“before”]=>
array(1) {
[“year”]=>
int(2010)
}
[“inclusive”]=>
bool(true)
}
}
but the WP_Query Class renders a SQL string within the WHERE clause:
… WHERE… post_date >= ‘2009-12-31 23:59:59’ AND post_date = ‘2009-01-01 00:00:00’ AND post_date <= '2010-12-31 23:59:59' )
Did I misunderstood the after-before-inclusive parameters? Or is there another way?
Known issue. See https://core.trac.wordpress.org/ticket/26653
There is an error in my last post: The rendered SQL string is
… WHERE … post_date >= ‘2009-12-31 23:59:59’ AND post_date = ‘2009-01-01 00:00:00’ AND post_date <= '2010-12-31 23:59:59' )
Pingback: What's wrong with my date_query? « Bay Area Web Design Bay Area Web Design
Pingback: Easy Wordpress date-queries | Code and the Gang
Hi Alex,
great work. I’m having some trouble to create a shortcode that displays the posts separated by week, but I’m not sure here is the right place to ask for your help. I posted it at the wordpress.org foruns in http://wordpress.org/support/topic/how-to-separate-the-posts-by-week , if you have the time and patience could you take a look please?
Thanks and keep up the excellent work!
Replied.
Pingback: Part three
Pingback: part 8
Pingback: PHP Function to Find Last Monday | var_dumpster
Pingback: ??WordPress????#5??????? | ??????
Pingback: A Look Into: WordPress Date Query | vienergie
Pingback: WordPress 3.7 Now Available | Articles From An Actual Living Web Professional
Hi Alex. I need to show 2 posts (one previous posts from today and next post from today) but I can’t figure out how to do it. I figure out how to get current month posts. Can you help me? Thanks in advance.
There’s lots of details at http://codex.wordpress.org/Function_Reference/WP_Query#Date_Parameters
You’ll want to use two queries and the
before
andafter
parameters. Usedate()
to get today.Pingback: WordPress Date Query
Pingback: More than 1 Year Date Query | ‹src.works/›
Hey, hello! Can you look at this question? https://wordpress.stackexchange.com/questions/285105/more-than-1-year-date-query
How to get posts from ‘many’ years like this? ‘year’ => array( 2016, 2017 ) So I want all posts from 2016 and 2017