Date Query Builder
Date ranges, rolling windows and calendar parts — with the column, timezone and off-by-one boundary gotchas called out before they bite.
// Generated with WP CodeKit — powered by GrowQuest (https://growquest.io). $args = array( 'post_type' => 'post', 'post_status' => 'publish', 'posts_per_page' => 10, 'date_query' => array( array( 'after' => '2026-01-01', 'before' => '2026-06-30', 'inclusive' => true, ), ), ); $query = new WP_Query( $args ); if ( $query->have_posts() ) { echo '<ul>'; while ( $query->have_posts() ) { $query->the_post(); printf( '<li><a href="%1$s">%2$s</a> <time datetime="%3$s">%4$s</time></li>', esc_url( get_permalink() ), esc_html( get_the_title() ), esc_attr( get_the_date( 'c' ) ), esc_html( get_the_date() ) ); } echo '</ul>'; wp_reset_postdata(); } else { esc_html_e( 'Nothing in that range.', 'mytheme' ); }
About this generator
Date Query Generator Online
Build the date_query argument in three shapes: a range between two dates, a rolling window such as the last 90 days, or calendar parts like "every December" and "weekday mornings". If you have been hunting for wp_query date_query examples that actually explain inclusive and the column choice, this generator writes them and flags the boundary mistakes as you make them.
A Reference tab restates the filter in plain English, documents each clause key, and lists the four wp_posts columns you can compare against with a note on when each is the right one. Free, no sign-up, everything computed in the browser.
Reviewed Output tested on WordPress 6.8 · PHP 8.3
Why the date_query builder beats guessing at before and after
WP_Date_Query is the most forgiving argument in WordPress, and that is the problem. Hand it a date it cannot parse and it drops the condition without a word; leave inclusive at its default and your "up to 30 June" report stops at midnight on the 30th, quietly losing a day of data. This generator checks the format, the ordering and the boundary before any of that reaches production.
The inclusive boundary is spelled out
With inclusive off and a Y-m-d boundary set, you get a warning stating exactly what happens — before 2026-06-30 stops at midnight, so nothing from the 30th matches — plus a one-click "Include the boundary" fix.
Unparseable dates are caught, not swallowed
A d-m-Y value is an error, because strtotime() reads it as something else entirely. Anything that is neither Y-m-d nor a recognisable relative phrase is a warning, since WP_Date_Query silently ignores what it cannot parse.
Impossible ranges rejected before they run
An after later than its before is an error with a "Swap them" fix. A range with both boundaries empty is an error too, because it means no filter at all rather than a wide one.
Calendar parts range-checked
Month outside 1-12, day outside 1-31, hour outside 0-23 and dayofweek outside 1-7 are each errors naming the bad value. dayofweek gets the note that 1 is Sunday, and that dayofweek_iso is the argument you want if Monday should be 1.
Timezone and status traps flagged
Comparing against post_date gets a tip to use post_date_gmt when the dates came from an API or a CSV in UTC, with a one-click switch. A future-facing range combined with post_status => publish warns that scheduled posts carry the future status, and offers to change it.
Honest about rolling windows
A relative window is evaluated at query time, so its result changes on every request and never settles in the object cache. The generator says so instead of letting you discover it in a cache-hit-rate graph.
How does the date query generator work?
Pick the shape of the filter first — the rest of the form changes to match — then set the column and the query around it.
- 01
Choose the shape of the range
Between two dates, a rolling window, calendar parts, or no date filter at all. Only the fields that shape needs are shown.
- 02
Fill in the boundaries or the parts
For a range, set
afterandbeforeasY-m-d(or astrtotimephrase) and decide whether the boundary days count. For a window, set a count and a unit. For parts, fill any of year, month, day, dayofweek and hour, comma separated for several. - 03
Pick the column
post_dateis local site time and is what the editor typed.post_date_gmtis UTC and is the right target for anything computed elsewhere.post_modifiedandpost_modified_gmtfind recently edited posts, including ones touched only for a typo. - 04
Set the query, clear the checks, export
Choose the post type, status, page size, sort direction and
no_found_rows, resolve the flagged issues, then copy the full query, the args array or thepre_get_postscallback.
Worked example — posts published in the first half of 2026, both boundary days included
A range clause with inclusive set to true, so 1 January and 30 June both count. Without it, before is treated as midnight at the start of the 30th and the whole of that day drops out.
$args = array(
'post_type' => 'post',
'post_status' => 'publish',
'posts_per_page' => 10,
'date_query' => array(
array(
'after' => '2026-01-01',
'before' => '2026-06-30',
'inclusive' => true,
),
),
);Note the double nesting: date_query is a list of clauses, so even a single condition is an array inside an array. Passing the inner array directly is the most common reason a date filter appears to do nothing. The column key is only emitted when you move off the post_date default.
date_query — frequently asked questions
The questions that come up whenever a date filter is off by a day or returns nothing.
What does inclusive do in a date_query, and why is my last day missing?
inclusive defaults to false, which means the boundary values are compared with > and < rather than >= and <=. Because a bare Y-m-d string resolves to midnight at the start of that day, before => 2026-06-30 with inclusive off excludes the whole of 30 June. Set inclusive => true, or pass a full 2026-06-30 23:59:59 timestamp.
Can I use relative dates like "-30 days" in a date_query?
Yes. after and before accept anything strtotime() understands, so -30 days, last monday and first day of this month all work. The catch is that unparseable input is discarded without an error, so a typo produces a query with no date condition rather than a failure. It is also evaluated per request, so a rolling window never produces a cacheable query.
What is the difference between post_date and post_date_gmt?
post_date is the publication time in the site timezone, which is what an editor sees in the admin. post_date_gmt is the same instant in UTC. If your boundaries came from an API, a CSV export or another system, they are almost certainly UTC and should be compared against post_date_gmt — comparing them to post_date shifts every result by your site offset, which looks correct in London in winter and wrong everywhere else.
Why does dayofweek return the wrong day?
There are two arguments. dayofweek runs 1 for Sunday through 7 for Saturday, matching MySQL DAYOFWEEK(). dayofweek_iso runs 1 for Monday through 7 for Sunday, matching ISO-8601 and WEEKDAY(). Using one set of numbers with the other argument shifts everything by a day.
How do I query scheduled or future posts by date?
Change the status as well as the range. A scheduled post has post_status of future, not publish, so a forward-looking after combined with the default publish status returns nothing at all. Set 'post_status' => 'future', or pass an array of both when you want published and upcoming items in one list.
Can I use date_query on user or comment queries too?
Yes. WP_User_Query accepts a date_query that is applied to the user_registered column, and WP_Comment_Query accepts one applied to comment_date_gmt. The clause keys are identical — the only thing that changes is which column the class targets by default.
Where do I paste the code from the WP_Date_Query generator?
You have three good options and one bad one. Best is a small site-specific plugin — the generator can output one for you, and it keeps working when you change theme. A code-snippets plugin is fine too. A child theme's functions.php works but ties the code to that theme. Never edit the parent theme: the next update overwrites it and your code is gone.
Can I use the generated code in client work or a commercial plugin?
Yes. The output is ordinary WordPress API calls that you configured — there is no licence attached to it and no attribution required. Use it in client sites, commercial plugins and themes, or products you sell. The generated file carries a short credit comment you are free to delete.
The other Query generators in the library, plus the WordPress tools most often used alongside this one.