Commit 5822422344c for woocommerce
commit 5822422344c337042cce2be2cd34252c4d8d80a7
Author: Vlad Olaru <vlad.olaru@automattic.com>
Date: Mon Nov 9 17:13:16 2026 +0200
Fix REST GMT date filters shifting dates with an explicit offset on non-UTC stores (#69719)
* fix(rest-api): Keep explicit offsets intact in GMT date filters
With `dates_are_gmt` set, the REST collection endpoints pass the raw
`before`, `after`, `modified_before` and `modified_after` strings to
`date_query` against the `*_gmt` columns. `WP_Date_Query` turns a full
timestamp that carries an offset (`Z`, `+00:00`, `+02:00`) into site
time before building the SQL, even for GMT columns. On a store outside
UTC, the boundary moves by the site offset and matching records drop
out of a 200 response. HPOS passes GMT-column values to the same code,
so both storage modes are affected.
Add `DateQueryUtil::to_gmt_date_query_value()`, which converts a date
that names its own offset or zone to the equivalent UTC
`Y-m-d H:i:s` string. `WP_Date_Query` passes that string through
unchanged. Use it in `WC_REST_CRUD_Controller::prepare_objects_query()`
(wc/v2 and wc/v3 orders, refunds, products, variations and coupons) and
in the V4 orders and refunds collection queries, only when
`dates_are_gmt` is set. Dates without an offset, `dates_are_gmt=0`
requests and unparsable values reach `date_query` byte-identical to
before.
The existing date-filter tests send `+00:00` dates on a UTC site,
which hid the bug. The new tests run on Europe/Athens, cover both
storage modes, and include boundaries that only match when the GMT
column is compared.
Refs #69714
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* refactor(rest-api): Reuse core rest_get_date_with_gmt() for GMT filters
DateQueryUtil parsed each offset date twice: date_parse() to detect a
zone, then DateTimeImmutable to convert it. WordPress core already ships
this conversion as rest_get_date_with_gmt( $date, true ), which
WooCommerce uses for product review dates.
Gate on the same offset pattern core uses and delegate the conversion
to core. That is one parse per value, and the accepted inputs now match
REST date-time validation exactly. Values without an offset still pass
through byte-identical.
The docblock no longer claims WP_Date_Query passes the result through
unchanged: it re-reads full timestamps as site time, which still shifts
a UTC time inside the spring-forward gap by an hour.
Refs #69714
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* refactor(rest-api): Move the GMT offset check into the query builders
Review asked to drop the DateQueryUtil class and call
rest_get_date_with_gmt() directly, while keeping the explicit-offset
check so dates without an offset still reach the object-query filters
unchanged.
The V2/V3 CRUD controller and the V4 collection queries share no
ancestor, so the check now lives on each base class:
WC_REST_CRUD_Controller gets a private static method, and
AbstractCollectionQuery a protected static one used by the V4 orders
and refunds builders. Private keeps the V3 copy off the surface that
extension subclasses can override. The behavior is unchanged.
The DateQueryUtil unit test cases move to the builders' outputs: the
V3 test asserts the date_query that the
woocommerce_rest_shop_order_object_query filter receives, for offset
and no-offset formats, and a V4 test covers no-offset values and the
fallback for an offset date that core can't parse.
Refs #69714
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Oleksandr Aratovskyi <79862886+oaratovskyi@users.noreply.github.com>
diff --git a/plugins/woocommerce/changelog/69714-fix-rest-gmt-date-filters b/plugins/woocommerce/changelog/69714-fix-rest-gmt-date-filters
new file mode 100644
index 00000000000..b82eba88dfc
--- /dev/null
+++ b/plugins/woocommerce/changelog/69714-fix-rest-gmt-date-filters
@@ -0,0 +1,4 @@
+Significance: patch
+Type: fix
+
+REST API date filters with dates_are_gmt now return the right results for UTC or offset dates on stores outside UTC.
diff --git a/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-crud-controller.php b/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-crud-controller.php
index b97855bd4e9..8d5f84a5ccc 100644
--- a/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-crud-controller.php
+++ b/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-crud-controller.php
@@ -310,28 +310,28 @@ abstract class WC_REST_CRUD_Controller extends WC_REST_Posts_Controller {
if ( isset( $request['before'] ) ) {
$date_query[] = array(
'column' => $use_gmt ? 'post_date_gmt' : 'post_date',
- 'before' => $request['before'],
+ 'before' => $use_gmt ? self::to_gmt_date_query_value( $request['before'] ) : $request['before'],
);
}
if ( isset( $request['after'] ) ) {
$date_query[] = array(
'column' => $use_gmt ? 'post_date_gmt' : 'post_date',
- 'after' => $request['after'],
+ 'after' => $use_gmt ? self::to_gmt_date_query_value( $request['after'] ) : $request['after'],
);
}
if ( isset( $request['modified_before'] ) ) {
$date_query[] = array(
'column' => $use_gmt ? 'post_modified_gmt' : 'post_modified',
- 'before' => $request['modified_before'],
+ 'before' => $use_gmt ? self::to_gmt_date_query_value( $request['modified_before'] ) : $request['modified_before'],
);
}
if ( isset( $request['modified_after'] ) ) {
$date_query[] = array(
'column' => $use_gmt ? 'post_modified_gmt' : 'post_modified',
- 'after' => $request['modified_after'],
+ 'after' => $use_gmt ? self::to_gmt_date_query_value( $request['modified_after'] ) : $request['modified_after'],
);
}
@@ -357,6 +357,26 @@ abstract class WC_REST_CRUD_Controller extends WC_REST_Posts_Controller {
return $this->prepare_items_query( $args, $request );
}
+ /**
+ * Convert a REST date that names its own UTC offset to the UTC 'Y-m-d H:i:s' form that GMT date columns store.
+ *
+ * WP_Date_Query re-expresses offset dates in the site timezone even when the column is GMT, shifting them by the site offset.
+ * Dates without an offset and values that can't be parsed are returned unchanged.
+ *
+ * @param mixed $date The date, usually an RFC 3339 string from a REST request.
+ * @return mixed The equivalent UTC date string, or the original value.
+ */
+ private static function to_gmt_date_query_value( $date ) {
+ // Same offset check as rest_get_date_with_gmt(), so values without one stay byte-identical.
+ if ( ! is_string( $date ) || ! preg_match( '#(Z|[+-]\d{2}(:\d{2})?)$#', $date ) ) {
+ return $date;
+ }
+
+ $dates = rest_get_date_with_gmt( $date, true );
+
+ return null === $dates ? $date : $dates[1];
+ }
+
/**
* Get objects.
*
diff --git a/plugins/woocommerce/src/Internal/RestApi/Routes/V4/AbstractCollectionQuery.php b/plugins/woocommerce/src/Internal/RestApi/Routes/V4/AbstractCollectionQuery.php
index 197e3c665d2..8f7394e3198 100644
--- a/plugins/woocommerce/src/Internal/RestApi/Routes/V4/AbstractCollectionQuery.php
+++ b/plugins/woocommerce/src/Internal/RestApi/Routes/V4/AbstractCollectionQuery.php
@@ -68,4 +68,26 @@ abstract class AbstractCollectionQuery {
* @return array
*/
abstract public function get_query_results( array $query_args, WP_REST_Request $request ): array;
+
+ /**
+ * Convert a REST date that names its own UTC offset to the UTC 'Y-m-d H:i:s' form that GMT date columns store.
+ *
+ * WP_Date_Query re-expresses offset dates in the site timezone even when the column is GMT, shifting them by the site offset.
+ * Dates without an offset and values that can't be parsed are returned unchanged.
+ *
+ * @since 11.4.0
+ *
+ * @param mixed $date The date, usually an RFC 3339 string from a REST request.
+ * @return mixed The equivalent UTC date string, or the original value.
+ */
+ protected static function to_gmt_date_query_value( $date ) {
+ // Same offset check as rest_get_date_with_gmt(), so values without one stay byte-identical.
+ if ( ! is_string( $date ) || ! preg_match( '#(Z|[+-]\d{2}(:\d{2})?)$#', $date ) ) {
+ return $date;
+ }
+
+ $dates = rest_get_date_with_gmt( $date, true );
+
+ return null === $dates ? $date : $dates[1];
+ }
}
diff --git a/plugins/woocommerce/src/Internal/RestApi/Routes/V4/Orders/CollectionQuery.php b/plugins/woocommerce/src/Internal/RestApi/Routes/V4/Orders/CollectionQuery.php
index 246379af319..d543939492a 100644
--- a/plugins/woocommerce/src/Internal/RestApi/Routes/V4/Orders/CollectionQuery.php
+++ b/plugins/woocommerce/src/Internal/RestApi/Routes/V4/Orders/CollectionQuery.php
@@ -209,28 +209,28 @@ class CollectionQuery extends AbstractCollectionQuery {
if ( isset( $request['before'] ) ) {
$date_query[] = array(
'column' => $use_gmt ? 'post_date_gmt' : 'post_date',
- 'before' => $request['before'],
+ 'before' => $use_gmt ? self::to_gmt_date_query_value( $request['before'] ) : $request['before'],
);
}
if ( isset( $request['after'] ) ) {
$date_query[] = array(
'column' => $use_gmt ? 'post_date_gmt' : 'post_date',
- 'after' => $request['after'],
+ 'after' => $use_gmt ? self::to_gmt_date_query_value( $request['after'] ) : $request['after'],
);
}
if ( isset( $request['modified_before'] ) ) {
$date_query[] = array(
'column' => $use_gmt ? 'post_modified_gmt' : 'post_modified',
- 'before' => $request['modified_before'],
+ 'before' => $use_gmt ? self::to_gmt_date_query_value( $request['modified_before'] ) : $request['modified_before'],
);
}
if ( isset( $request['modified_after'] ) ) {
$date_query[] = array(
'column' => $use_gmt ? 'post_modified_gmt' : 'post_modified',
- 'after' => $request['modified_after'],
+ 'after' => $use_gmt ? self::to_gmt_date_query_value( $request['modified_after'] ) : $request['modified_after'],
);
}
diff --git a/plugins/woocommerce/src/Internal/RestApi/Routes/V4/Refunds/CollectionQuery.php b/plugins/woocommerce/src/Internal/RestApi/Routes/V4/Refunds/CollectionQuery.php
index 2fece88d224..8b44242c781 100644
--- a/plugins/woocommerce/src/Internal/RestApi/Routes/V4/Refunds/CollectionQuery.php
+++ b/plugins/woocommerce/src/Internal/RestApi/Routes/V4/Refunds/CollectionQuery.php
@@ -119,14 +119,14 @@ class CollectionQuery extends AbstractCollectionQuery {
if ( isset( $request['before'] ) ) {
$date_query[] = array(
'column' => $use_gmt ? 'post_date_gmt' : 'post_date',
- 'before' => $request['before'],
+ 'before' => $use_gmt ? self::to_gmt_date_query_value( $request['before'] ) : $request['before'],
);
}
if ( isset( $request['after'] ) ) {
$date_query[] = array(
'column' => $use_gmt ? 'post_date_gmt' : 'post_date',
- 'after' => $request['after'],
+ 'after' => $use_gmt ? self::to_gmt_date_query_value( $request['after'] ) : $request['after'],
);
}
diff --git a/plugins/woocommerce/tests/php/includes/rest-api/Controllers/Version3/class-wc-rest-orders-controller-tests.php b/plugins/woocommerce/tests/php/includes/rest-api/Controllers/Version3/class-wc-rest-orders-controller-tests.php
index e83788d6800..b438d379eeb 100644
--- a/plugins/woocommerce/tests/php/includes/rest-api/Controllers/Version3/class-wc-rest-orders-controller-tests.php
+++ b/plugins/woocommerce/tests/php/includes/rest-api/Controllers/Version3/class-wc-rest-orders-controller-tests.php
@@ -250,6 +250,128 @@ class WC_REST_Orders_Controller_Tests extends WC_REST_Unit_Test_Case {
$this->assertCount( 5, $response->get_data() );
}
+ /**
+ * @testdox GMT date filters should treat a date with an explicit offset as the same instant on a non-UTC site.
+ *
+ * @dataProvider data_provider_gmt_date_filters_with_offset
+ *
+ * @param bool $hpos_enabled Whether HPOS is the authoritative order storage.
+ * @param string $param The date filter parameter.
+ * @param string $value The date filter value.
+ * @param bool $expect_matched Whether the order should be returned.
+ */
+ public function test_orders_gmt_date_filters_respect_explicit_offsets( bool $hpos_enabled, string $param, string $value, bool $expect_matched ): void {
+ global $wpdb;
+
+ $this->toggle_cot_feature_and_usage( $hpos_enabled );
+ update_option( 'timezone_string', 'Europe/Athens' );
+
+ $utc_date = '2026-09-24 14:40:20';
+ $order = new WC_Order();
+ $order->set_date_created( strtotime( $utc_date . ' UTC' ) );
+ $order->save();
+
+ // Saving stamps the current time as the modification date, so pin it in storage.
+ if ( $hpos_enabled ) {
+ $wpdb->update( OrdersTableDataStore::get_orders_table_name(), array( 'date_updated_gmt' => $utc_date ), array( 'id' => $order->get_id() ) );
+ } else {
+ $wpdb->update( $wpdb->posts, array( 'post_modified_gmt' => $utc_date ), array( 'ID' => $order->get_id() ) );
+ }
+
+ $request = new WP_REST_Request( 'GET', '/wc/v3/orders' );
+ $request->set_param( 'include', array( $order->get_id() ) );
+ $request->set_param( 'dates_are_gmt', true );
+ $request->set_param( $param, $value );
+ $response = $this->server->dispatch( $request );
+
+ $this->assertSame( 200, $response->get_status() );
+ $this->assertSame(
+ $expect_matched ? array( $order->get_id() ) : array(),
+ wp_list_pluck( $response->get_data(), 'id' ),
+ "Order modified and created at {$utc_date} UTC should " . ( $expect_matched ? '' : 'not ' ) . "match {$param}={$value}."
+ );
+ }
+
+ /**
+ * Data provider for test_orders_gmt_date_filters_respect_explicit_offsets.
+ *
+ * @return array
+ */
+ public function data_provider_gmt_date_filters_with_offset(): array {
+ $cases = array(
+ 'after, Z' => array( 'after', '2026-09-24T14:39:52Z', true ),
+ 'before, Z' => array( 'before', '2026-09-24T14:39:52Z', false ),
+ 'modified_after, Z' => array( 'modified_after', '2026-09-24T14:39:52Z', true ),
+ 'modified_before, Z' => array( 'modified_before', '2026-09-24T14:39:52Z', false ),
+ 'modified_after, +02:00' => array( 'modified_after', '2026-09-24T16:00:00+02:00', true ),
+ 'modified_before, +02:00' => array( 'modified_before', '2026-09-24T16:00:00+02:00', false ),
+ 'modified_after, no offset' => array( 'modified_after', '2026-09-24T14:39:52', true ),
+ 'modified_before, no offset' => array( 'modified_before', '2026-09-24T14:39:52', false ),
+ // Boundaries between the order's UTC and local times only match when the GMT columns are compared.
+ 'after, Z, later' => array( 'after', '2026-09-24T15:00:00Z', false ),
+ 'before, Z, later' => array( 'before', '2026-09-24T15:00:00Z', true ),
+ 'modified_after, Z, later' => array( 'modified_after', '2026-09-24T15:00:00Z', false ),
+ 'modified_before, Z, later' => array( 'modified_before', '2026-09-24T15:00:00Z', true ),
+ );
+
+ $storage_modes = array(
+ 'HPOS' => true,
+ 'posts' => false,
+ );
+
+ $data = array();
+ foreach ( $storage_modes as $storage => $hpos_enabled ) {
+ foreach ( $cases as $label => $case ) {
+ $data[ "{$storage}: {$label}" ] = array_merge( array( $hpos_enabled ), $case );
+ }
+ }
+
+ return $data;
+ }
+
+ /**
+ * @testdox GMT date filters should pass offset dates to the object query filter as UTC, and other dates unchanged.
+ *
+ * @testWith ["2026-09-24T14:39:52Z", "2026-09-24 14:39:52"]
+ * ["2026-09-24T16:39:52+02:00", "2026-09-24 14:39:52"]
+ * ["2026-09-24T16:39:52+02", "2026-09-24 14:39:52"]
+ * ["2026-09-24T09:09:52-05:30", "2026-09-24 14:39:52"]
+ * ["2026-09-24T14:39:52.750Z", "2026-09-24 14:39:52"]
+ * ["2026-09-25T00:30:00+03:00", "2026-09-24 21:30:00"]
+ * ["2026-09-24T14:39:52", "2026-09-24T14:39:52"]
+ * ["2026-09-24 14:39:52", "2026-09-24 14:39:52"]
+ * ["2026-09-24T14:39:52.123", "2026-09-24T14:39:52.123"]
+ *
+ * @param string $value The date filter value.
+ * @param string $expected The value expected in the object query.
+ */
+ public function test_orders_gmt_date_filters_pass_utc_values_to_object_query( string $value, string $expected ): void {
+ update_option( 'timezone_string', 'Europe/Athens' );
+
+ $date_query = null;
+ add_filter(
+ 'woocommerce_rest_shop_order_object_query',
+ function ( $args ) use ( &$date_query ) {
+ $date_query = $args['date_query'] ?? null;
+ return $args;
+ }
+ );
+
+ $request = new WP_REST_Request( 'GET', '/wc/v3/orders' );
+ $request->set_param( 'dates_are_gmt', true );
+ $request->set_param( 'after', $value );
+ $response = $this->server->dispatch( $request );
+
+ $this->assertSame( 200, $response->get_status() );
+ $this->assertContains(
+ array(
+ 'column' => 'post_date_gmt',
+ 'after' => $expected,
+ ),
+ $date_query
+ );
+ }
+
/**
* Tests creating an order.
*/
diff --git a/plugins/woocommerce/tests/php/includes/rest-api/Controllers/Version4/Orders/class-wc-rest-orders-v4-controller-tests.php b/plugins/woocommerce/tests/php/includes/rest-api/Controllers/Version4/Orders/class-wc-rest-orders-v4-controller-tests.php
index b90ae8ee5a6..4a2061a0257 100644
--- a/plugins/woocommerce/tests/php/includes/rest-api/Controllers/Version4/Orders/class-wc-rest-orders-v4-controller-tests.php
+++ b/plugins/woocommerce/tests/php/includes/rest-api/Controllers/Version4/Orders/class-wc-rest-orders-v4-controller-tests.php
@@ -4,6 +4,7 @@ use Automattic\WooCommerce\Enums\OrderStatus;
use Automattic\WooCommerce\Internal\DataStores\Orders\CustomOrdersTableController;
use Automattic\WooCommerce\RestApi\UnitTests\HPOSToggleTrait;
use Automattic\WooCommerce\Proxies\LegacyProxy;
+use Automattic\WooCommerce\Internal\RestApi\Routes\V4\Orders\CollectionQuery;
use Automattic\WooCommerce\Internal\RestApi\Routes\V4\Orders\Controller as OrdersController;
use Automattic\WooCommerce\Internal\RestApi\Routes\V4\Orders\Schema\OrderSchema;
use Automattic\WooCommerce\Internal\RestApi\Routes\V4\Orders\Schema\OrderItemSchema;
@@ -1051,6 +1052,98 @@ class WC_REST_Orders_V4_Controller_Tests extends WC_REST_Unit_Test_Case {
$order2->delete( true );
}
+ /**
+ * @testdox GMT date filters should pass dates with an explicit offset to the query as the equivalent UTC time.
+ */
+ public function test_get_query_args_converts_offset_dates_for_gmt_filters(): void {
+ update_option( 'timezone_string', 'Europe/Athens' );
+
+ $request = new WP_REST_Request( 'GET', '/wc/v4/orders' );
+ $request->set_param( 'dates_are_gmt', true );
+ $request->set_param( 'after', '2026-09-24T16:39:52+02:00' );
+ $request->set_param( 'before', '2026-09-24T14:39:52Z' );
+ $request->set_param( 'modified_after', '2026-09-24T14:39:52+00:00' );
+ $request->set_param( 'modified_before', '2026-09-24T17:39:52+03:00' );
+
+ $date_query = ( new CollectionQuery() )->get_query_args( $request )['date_query'];
+
+ $this->assertContains(
+ array(
+ 'column' => 'post_date_gmt',
+ 'after' => '2026-09-24 14:39:52',
+ ),
+ $date_query
+ );
+ $this->assertContains(
+ array(
+ 'column' => 'post_date_gmt',
+ 'before' => '2026-09-24 14:39:52',
+ ),
+ $date_query
+ );
+ $this->assertContains(
+ array(
+ 'column' => 'post_modified_gmt',
+ 'after' => '2026-09-24 14:39:52',
+ ),
+ $date_query
+ );
+ $this->assertContains(
+ array(
+ 'column' => 'post_modified_gmt',
+ 'before' => '2026-09-24 14:39:52',
+ ),
+ $date_query
+ );
+ }
+
+ /**
+ * @testdox GMT date filters should pass dates without an offset, and offset dates that can't be parsed, to the query unchanged.
+ *
+ * @testWith ["2026-09-24T14:39:52"]
+ * ["2026-09-24T14:39:52.123"]
+ * ["not a dateZ"]
+ *
+ * @param string $value The date filter value.
+ */
+ public function test_get_query_args_keeps_other_dates_for_gmt_filters( string $value ): void {
+ update_option( 'timezone_string', 'Europe/Athens' );
+
+ $request = new WP_REST_Request( 'GET', '/wc/v4/orders' );
+ $request->set_param( 'dates_are_gmt', true );
+ $request->set_param( 'after', $value );
+
+ $date_query = ( new CollectionQuery() )->get_query_args( $request )['date_query'];
+
+ $this->assertContains(
+ array(
+ 'column' => 'post_date_gmt',
+ 'after' => $value,
+ ),
+ $date_query
+ );
+ }
+
+ /**
+ * @testdox Local date filters should pass dates with an explicit offset to the query unchanged.
+ */
+ public function test_get_query_args_keeps_offset_dates_for_local_filters(): void {
+ update_option( 'timezone_string', 'Europe/Athens' );
+
+ $request = new WP_REST_Request( 'GET', '/wc/v4/orders' );
+ $request->set_param( 'modified_after', '2026-09-24T14:39:52Z' );
+
+ $date_query = ( new CollectionQuery() )->get_query_args( $request )['date_query'];
+
+ $this->assertContains(
+ array(
+ 'column' => 'post_modified',
+ 'after' => '2026-09-24T14:39:52Z',
+ ),
+ $date_query
+ );
+ }
+
/**
* Test status filtering.
*/
diff --git a/plugins/woocommerce/tests/php/includes/rest-api/Controllers/Version4/Refunds/class-wc-rest-refunds-v4-controller-tests.php b/plugins/woocommerce/tests/php/includes/rest-api/Controllers/Version4/Refunds/class-wc-rest-refunds-v4-controller-tests.php
index cadad960a6e..35218b00d55 100644
--- a/plugins/woocommerce/tests/php/includes/rest-api/Controllers/Version4/Refunds/class-wc-rest-refunds-v4-controller-tests.php
+++ b/plugins/woocommerce/tests/php/includes/rest-api/Controllers/Version4/Refunds/class-wc-rest-refunds-v4-controller-tests.php
@@ -455,6 +455,35 @@ class WC_REST_Refunds_V4_Controller_Tests extends WC_REST_Unit_Test_Case {
$this->assertEquals( $order2->get_id(), $response_data[0]['order_id'] );
}
+ /**
+ * @testdox GMT date filters should pass dates with an explicit offset to the query as the equivalent UTC time.
+ */
+ public function test_get_query_args_converts_offset_dates_for_gmt_filters(): void {
+ update_option( 'timezone_string', 'Europe/Athens' );
+
+ $request = new WP_REST_Request( 'GET', '/wc/v4/refunds' );
+ $request->set_param( 'dates_are_gmt', true );
+ $request->set_param( 'after', '2026-09-24T16:39:52+02:00' );
+ $request->set_param( 'before', '2026-09-24T14:39:52Z' );
+
+ $date_query = ( new CollectionQuery() )->get_query_args( $request )['date_query'];
+
+ $this->assertContains(
+ array(
+ 'column' => 'post_date_gmt',
+ 'after' => '2026-09-24 14:39:52',
+ ),
+ $date_query
+ );
+ $this->assertContains(
+ array(
+ 'column' => 'post_date_gmt',
+ 'before' => '2026-09-24 14:39:52',
+ ),
+ $date_query
+ );
+ }
+
/**
* Test refund creation with line items.
*/