WooCommerce后台订单列表(HPOS)日期范围筛选异常问题
问题:WooCommerce后台订单日期范围筛选,同一日期时无法正确过滤
我尝试在WooCommerce后台订单列表添加「按日期范围筛选」功能,使用了以下PHP代码,但当选择同一日期(如9月1日至9月1日)时,仍会显示该日期前后的订单,请问我哪里出错了?
function ts_add_date_range_filter($post_type) { if ('shop_order' === $post_type) { ?> <label for="from_date"><?php _e('From Date:', 'woocommerce'); ?></label> <input type="date" id="from_date" name="from_date" value="<?php echo isset($_GET['from_date']) ? esc_attr($_GET['from_date']) : ''; ?>" /> <label for="to_date"><?php _e('To Date:', 'woocommerce'); ?></label> <input type="date" id="to_date" name="to_date" value="<?php echo isset($_GET['to_date']) ? esc_attr($_GET['to_date']) : ''; ?>" /> <?php } } add_action('woocommerce_order_list_table_restrict_manage_orders', 'ts_add_date_range_filter'); function ts_filter_orders_by_date_range($vars) { if (!isset($vars['date_query'])) { $vars['date_query'] = array(); } if (isset($_GET['from_date']) && !empty($_GET['from_date'])) { $vars['date_query'][] = array( 'after' => sanitize_text_field($_GET['from_date']), 'inclusive' => true, ); } if (isset($_GET['to_date']) && !empty($_GET['to_date'])) { $vars['date_query'][] = array( 'before' => sanitize_text_field($_GET['to_date']), 'inclusive' => true, ); } return $vars; } add_filter('woocommerce_order_list_table_prepare_items_query_args', 'ts_filter_orders_by_date_range');
错误原因分析
日期解析逻辑问题:当只传递
YYYY-MM-DD格式的日期给before参数时,WordPress会自动将其解析为当天的00:00:00,这意味着当天0点之后创建的订单都会被排除在筛选结果之外,和你期望的「包含当天所有订单」不符。date_query结构不合理:你将
after和before拆分成两个独立的date_query子数组,虽然默认逻辑是AND,但这种写法可能导致潜在的逻辑冲突,正确的做法是将两个条件放在同一个子数组中。
修正后的代码
function ts_add_date_range_filter($post_type) { if ('shop_order' === $post_type) { ?> <label for="from_date"><?php _e('From Date:', 'woocommerce'); ?></label> <input type="date" id="from_date" name="from_date" value="<?php echo isset($_GET['from_date']) ? esc_attr($_GET['from_date']) : ''; ?>" /> <label for="to_date"><?php _e('To Date:', 'woocommerce'); ?></label> <input type="date" id="to_date" name="to_date" value="<?php echo isset($_GET['to_date']) ? esc_attr($_GET['to_date']) : ''; ?>" /> <?php } } add_action('woocommerce_order_list_table_restrict_manage_orders', 'ts_add_date_range_filter'); function ts_filter_orders_by_date_range($vars) { // 初始化date_query数组,确保结构正确 if (!isset($vars['date_query']) || !is_array($vars['date_query'])) { $vars['date_query'] = array( 'relation' => 'AND', // 显式设置条件关系为AND ); } $date_query = array(); if (isset($_GET['from_date']) && !empty($_GET['from_date'])) { $date_query['after'] = sanitize_text_field($_GET['from_date']); $date_query['inclusive'] = true; } if (isset($_GET['to_date']) && !empty($_GET['to_date'])) { // 将结束日期设置为当天的23:59:59,确保包含当天所有订单 $date_query['before'] = sanitize_text_field($_GET['to_date']) . ' 23:59:59'; $date_query['inclusive'] = true; } // 如果有筛选条件,添加到date_query中 if (!empty($date_query)) { $vars['date_query'][] = $date_query; } return $vars; } add_filter('woocommerce_order_list_table_prepare_items_query_args', 'ts_filter_orders_by_date_range');
关键修改点
- 处理结束日期:在
to_date的日期后拼接23:59:59,确保WordPress将结束时间识别为当天的最后一秒,包含当天所有时间段的订单。 - 统一date_query结构:将
after和before条件合并到同一个子数组中,并显式设置relation为AND,让筛选逻辑更清晰且避免冲突。
内容的提问来源于stack exchange,提问作者javitoor1001
相关产品推荐
相关产品推荐

