在 WordPress 开发中,我们经常需要根据时间范围来筛选文章,比如显示最近一周的热门文章、查询特定时间段内的内容、或者创建基于时间的归档页面。本文将详细介绍多种实现 WordPress 搜索指定时间内文章的方法。
一、为什么需要时间范围搜索?
- 内容时效性:显示最新或特定时间段内的文章
- 数据分析:统计某段时间内的内容产出
- 专题聚合:创建节日、活动期间的专题页面
- 用户行为:根据用户访问时间显示相关内容
- SEO优化:突出时效性内容,提高搜索排名
二、使用 WP_Query 的时间参数
WordPress 的 WP_Query类提供了强大的时间查询功能,主要通过 date_query参数实现。
基础语法结构
$args = array(
'post_type' => 'post',
'posts_per_page' => -1,
'date_query' => array(
// 时间查询条件
)
);
$query = new WP_Query($args);
三、具体实现方法
1. 搜索特定日期范围内的文章
/**
* 搜索指定日期范围内的文章
*
* @param string $start_date 开始日期 (格式: YYYY-MM-DD)
* @param string $end_date 结束日期 (格式: YYYY-MM-DD)
* @return WP_Query
*/
function search_posts_by_date_range($start_date, $end_date) {
$args = array(
'post_type' => 'post',
'post_status' => 'publish',
'posts_per_page' => -1,
'date_query' => array(
array(
'after' => $start_date,
'before' => $end_date,
'inclusive' => true, // 包含开始和结束日期
)
),
'orderby' => 'date',
'order' => 'DESC',
);
return new WP_Query($args);
}
// 使用示例:搜索2026年1月1日到2026年2月17日之间的文章
$start_date = '2026-01-01';
$end_date = '2026-02-17';
$query = search_posts_by_date_range($start_date, $end_date);
if ($query->have_posts()) {
while ($query->have_posts()) {
$query->the_post();
the_title('<h2>', '</h2>');
echo '<p>发布日期: ' . get_the_date() . '</p>';
}
wp_reset_postdata();
} else {
echo '该时间段内没有文章。';
}
2. 搜索最近 N 天内的文章
/**
* 搜索最近 N 天内的文章
*
* @param int $days 天数
* @return WP_Query
*/
function search_recent_posts_by_days($days = 7) {
$args = array(
'post_type' => 'post',
'post_status' => 'publish',
'posts_per_page' => 10,
'date_query' => array(
array(
'after' => $days . ' days ago',
)
),
'orderby' => 'date',
'order' => 'DESC',
);
return new WP_Query($args);
}
// 使用示例:搜索最近30天内的文章
$recent_query = search_recent_posts_by_days(30);
if ($recent_query->have_posts()) {
echo '<h3>最近30天的文章:</h3>';
while ($recent_query->have_posts()) {
$recent_query->the_post();
echo '<li>' . get_the_title() . ' (' . get_the_date() . ')</li>';
}
wp_reset_postdata();
}
3. 搜索特定月份的文章
/**
* 搜索特定年份和月份的文章
*
* @param int $year 年份
* @param int $month 月份
* @return WP_Query
*/
function search_posts_by_month($year, $month) {
$args = array(
'post_type' => 'post',
'post_status' => 'publish',
'posts_per_page' => -1,
'date_query' => array(
array(
'year' => $year,
'month' => $month,
)
),
'orderby' => 'date',
'order' => 'DESC',
);
return new WP_Query($args);
}
// 使用示例:搜索2026年1月的文章
$month_query = search_posts_by_month(2026, 1);
4. 搜索特定季度的文章
/**
* 搜索特定季度的文章
*
* @param int $year 年份
* @param int $quarter 季度 (1-4)
* @return WP_Query
*/
function search_posts_by_quarter($year, $quarter) {
// 计算季度的开始和结束月份
$start_month = (($quarter - 1) * 3) + 1;
$end_month = $start_month + 2;
$args = array(
'post_type' => 'post',
'post_status' => 'publish',
'posts_per_page' => -1,
'date_query' => array(
array(
'year' => $year,
'month' => array($start_month, $end_month),
'compare' => 'BETWEEN',
)
),
'orderby' => 'date',
'order' => 'DESC',
);
return new WP_Query($args);
}
// 使用示例:搜索2026年第一季度的文章
$quarter_query = search_posts_by_quarter(2026, 1);
5. 搜索今天发布的文章
/**
* 搜索今天发布的文章
*/
function search_todays_posts() {
$today = date('Y-m-d');
$args = array(
'post_type' => 'post',
'post_status' => 'publish',
'posts_per_page' => -1,
'date_query' => array(
array(
'year' => date('Y'),
'month' => date('m'),
'day' => date('d'),
)
),
);
$query = new WP_Query($args);
if ($query->have_posts()) {
echo '<h3>今天发布的文章:</h3>';
while ($query->have_posts()) {
$query->the_post();
echo '<li>' . get_the_title() . '</li>';
}
} else {
echo '<p>今天还没有发布文章。</p>';
}
wp_reset_postdata();
}
四、创建时间范围搜索表单
1. 简单搜索表单
/**
* 时间范围搜索表单
*/
function time_range_search_form() {
?>
<form method="get" action="<?php echo esc_url(home_url('/')); ?>">
<h3>按时间范围搜索文章</h3>
<div>
<label for="start_date">开始日期:</label>
<input type="date" id="start_date" name="start_date"
value="<?php echo isset($_GET['start_date']) ? esc_attr($_GET['start_date']) : ''; ?>">
</div>
<div>
<label for="end_date">结束日期:</label>
<input type="date" id="end_date" name="end_date"
value="<?php echo isset($_GET['end_date']) ? esc_attr($_GET['end_date']) : ''; ?>">
</div>
<input type="hidden" name="time_search" value="1">
<input type="submit" value="搜索">
</form>
<?php
}
2. 处理搜索请求
/**
* 处理时间范围搜索
*/
function handle_time_range_search($query) {
if (is_admin() || !$query->is_main_query()) {
return;
}
if (isset($_GET['time_search']) && $_GET['time_search'] == '1') {
if (!empty($_GET['start_date']) && !empty($_GET['end_date'])) {
$date_query = array(
array(
'after' => sanitize_text_field($_GET['start_date']),
'before' => sanitize_text_field($_GET['end_date']),
'inclusive' => true,
)
);
$query->set('date_query', $date_query);
}
}
}
add_action('pre_get_posts', 'handle_time_range_search');
五、高级时间查询示例
1. 多个时间条件组合
/**
* 复杂的多条件时间查询
*/
function complex_date_query_example() {
$args = array(
'post_type' => 'post',
'posts_per_page' => 10,
'date_query' => array(
'relation' => 'OR',
array(
'year' => 2026,
'month' => 1,
),
array(
'year' => 2026,
'month' => 2,
'day' => array(1, 2, 3, 4, 5), // 2月1-5日
),
array(
'after' => '2026-02-10',
'before' => '2026-02-20',
),
),
);
$query = new WP_Query($args);
return $query;
}
2. 排除特定时间段的文章
/**
* 排除特定时间段的文章
*/
function exclude_specific_time_period() {
$args = array(
'post_type' => 'post',
'posts_per_page' => 10,
'date_query' => array(
array(
'after' => '2026-01-01',
),
array(
'column' => 'post_date',
'before' => '2026-01-10',
'compare' => '!=', // 排除1月1日到1月10日
)
),
);
$query = new WP_Query($args);
return $query;
}
六、创建时间范围搜索小工具
/**
* 时间范围搜索小工具
*/
class Time_Range_Search_Widget extends WP_Widget {
public function __construct() {
parent::__construct(
'time_range_search_widget',
__('时间范围搜索', 'text-domain'),
array('description' => __('按时间范围搜索文章', 'text-domain'))
);
}
public function widget($args, $instance) {
echo $args['before_widget'];
if (!empty($instance['title'])) {
echo $args['before_title'] . apply_filters('widget_title', $instance['title']) . $args['after_title'];
}
?>
<form method="get" action="<?php echo esc_url(home_url('/')); ?>" class="time-range-search-form">
<div class="form-group">
<label for="start_date_<?php echo $this->id; ?>"><?php _e('开始日期:', 'text-domain'); ?></label>
<input type="date" id="start_date_<?php echo $this->id; ?>" name="start_date"
class="widefat" value="<?php echo isset($_GET['start_date']) ? esc_attr($_GET['start_date']) : date('Y-m-d', strtotime('-1 month')); ?>">
</div>
<div class="form-group">
<label for="end_date_<?php echo $this->id; ?>"><?php _e('结束日期:', 'text-domain'); ?></label>
<input type="date" id="end_date_<?php echo $this->id; ?>" name="end_date"
class="widefat" value="<?php echo isset($_GET['end_date']) ? esc_attr($_GET['end_date']) : date('Y-m-d'); ?>">
</div>
<input type="hidden" name="time_search" value="1">
<input type="submit" class="button" value="<?php _e('搜索', 'text-domain'); ?>">
</form>
<?php
echo $args['after_widget'];
}
public function form($instance) {
$title = !empty($instance['title']) ? $instance['title'] : __('时间范围搜索', 'text-domain');
?>
<p>
<label for="<?php echo esc_attr($this->get_field_id('title')); ?>">
<?php _e('标题:', 'text-domain'); ?>
</label>
<input class="widefat" id="<?php echo esc_attr($this->get_field_id('title')); ?>"
name="<?php echo esc_attr($this->get_field_name('title')); ?>"
type="text" value="<?php echo esc_attr($title); ?>">
</p>
<?php
}
public function update($new_instance, $old_instance) {
$instance = array();
$instance['title'] = (!empty($new_instance['title'])) ? strip_tags($new_instance['title']) : '';
return $instance;
}
}
// 注册小工具
function register_time_range_search_widget() {
register_widget('Time_Range_Search_Widget');
}
add_action('widgets_init', 'register_time_range_search_widget');
七、性能优化建议
1. 添加缓存机制
/**
* 带缓存的时间范围查询
*/
function cached_posts_by_date_range($start_date, $end_date) {
$cache_key = 'posts_date_range_' . $start_date . '_' . $end_date;
$cached_data = wp_cache_get($cache_key, 'posts');
if (false === $cached_data) {
$args = array(
'post_type' => 'post',
'posts_per_page' => -1,
'date_query' => array(
array(
'after' => $start_date,
'before' => $end_date,
'inclusive' => true,
)
),
'fields' => 'ids', // 只获取ID,减少数据量
);
$query = new WP_Query($args);
$cached_data = $query->posts;
// 缓存1小时
wp_cache_set($cache_key, $cached_data, 'posts', HOUR_IN_SECONDS);
}
return $cached_data;
}
2. 使用数据库查询优化
/**
* 使用原始SQL查询提高性能
*/
function search_posts_by_date_range_sql($start_date, $end_date) {
global $wpdb;
$sql = $wpdb->prepare(
"SELECT ID, post_title, post_date
FROM {$wpdb->posts}
WHERE post_type = 'post'
AND post_status = 'publish'
AND post_date >= %s
AND post_date <= %s
ORDER BY post_date DESC",
$start_date . ' 00:00:00',
$end_date . ' 23:59:59'
);
return $wpdb->get_results($sql);
}
八、实际应用场景
1. 创建”最近更新”区块
/**
* 显示最近7天更新的文章
*/
function display_recently_updated_posts() {
$args = array(
'post_type' => 'post',
'posts_per_page' => 5,
'date_query' => array(
array(
'column' => 'post_modified',
'after' => '7 days ago',
)
),
'orderby' => 'modified',
'order' => 'DESC',
);
$query = new WP_Query($args);
if ($query->have_posts()) {
echo '<div class="recently-updated">';
echo '<h3>最近7天更新的文章</h3>';
echo '<ul>';
while ($query->have_posts()) {
$query->the_post();
$modified_date = get_the_modified_date();
echo '<li>';
echo '<a href="' . get_permalink() . '">' . get_the_title() . '</a>';
echo '<span class="modified-date">(更新于:' . $modified_date . ')</span>';
echo '</li>';
}
echo '</ul>';
echo '</div>';
}
wp_reset_postdata();
}
2. 节日专题页面
/**
* 马年春节专题文章
*/
function display_cny_special_posts() {
// 2026年马年春节期间
$args = array(
'post_type' => 'post',
'posts_per_page' => -1,
'date_query' => array(
array(
'after' => '2026-01-20', // 春节前一周
'before' => '2026-02-24', // 元宵节后一周
)
),
'tax_query' => array(
array(
'taxonomy' => 'category',
'field' => 'slug',
'terms' => array('festival', 'cny', 'new-year'),
)
),
);
$query = new WP_Query($args);
if ($query->have_posts()) {
echo '<div class="cny-special">';
echo '<h2>🐎 2026丙午马年春节专题</h2>';
while ($query->have_posts()) {
$query->the_post();
// 显示文章内容
}
echo '</div>';
}
wp_reset_postdata();
}
九、注意事项
- 时区问题:确保 WordPress 时区设置正确
- 日期格式:使用正确的日期格式(YYYY-MM-DD)
- 性能考虑:大量数据查询时考虑分页
- 安全验证:用户输入必须进行验证和清理
- 缓存策略:频繁查询的数据应该缓存
- 错误处理:添加适当的错误处理机制
十、完整示例:时间范围搜索页面模板
创建一个名为 template-time-search.php的页面模板:
<?php
/**
* Template Name: 时间范围搜索
*/
get_header();
// 处理搜索
if (isset($_GET['search_time'])) {
$start_date = sanitize_text_field($_GET['start_date']);
$end_date = sanitize_text_field($_GET['end_date']);
$args = array(
'post_type' => 'post',
'posts_per_page' => 10,
'paged' => get_query_var('paged') ? get_query_var('paged') : 1,
);
if (!empty($start_date) && !empty($end_date)) {
$args['date_query'] = array(
array(
'after' => $start_date,
'before' => $end_date,
'inclusive' => true,
)
);
}
$search_query = new WP_Query($args);
}
?>
<div class="time-search-page">
<h1><?php the_title(); ?></h1>
<!-- 搜索表单 -->
<div class="time-search-form">
<form method="get" action="">
<input type="hidden" name="search_time" value="1">
<div class="form-row">
<label for="start_date">开始日期:</label>
<input type="date" id="start_date" name="start_date"
value="<?php echo isset($_GET['start_date']) ? esc_attr($_GET['start_date']) : ''; ?>" required>
</div>
<div class="form-row">
<label for="end_date">结束日期:</label>
<input type="date" id="end_date" name="end_date"
value="<?php echo isset($_GET['end_date']) ? esc_attr($_GET['end_date']) : ''; ?>" required>
</div>
<input type="submit" value="搜索文章" class="btn btn-primary">
</form>
</div>
<!-- 搜索结果 -->
<?php if (isset($search_query)) : ?>
<div class="search-results">
<h2>搜索结果</h2>
<?php if ($search_query->have_posts()) : ?>
<p>找到 <?php echo $search_query->found_posts; ?> 篇文章</p>
<div class="posts-list">
<?php while ($search_query->have_posts()) : $search_query->the_post(); ?>
<article class="post-item">
<h3><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h3>
<div class="post-meta">
<span class="date">发布日期:<?php echo get_the_date(); ?></span>
</div>
<div class="excerpt"><?php the_excerpt(); ?></div>
</article>
<?php endwhile; ?>
</div>
<!-- 分页 -->
<?php
$pagination = paginate_links(array(
'total' => $search_query->max_num_pages,
'current' => max(1, get_query_var('paged')),
'prev_text' => __('« 上一页'),
'next_text' => __('下一页 »'),
));
if ($pagination) {
echo '<div class="pagination">' . $pagination . '</div>';
}
?>
<?php else : ?>
<p>没有找到指定时间范围内的文章。</p>
<?php endif; ?>
<?php wp_reset_postdata(); ?>
</div>
<?php endif; ?>
</div>
<?php get_footer(); ?>
总结
WordPress 的时间范围搜索功能非常强大,通过 date_query参数可以实现各种复杂的时间筛选需求。无论是简单的日期范围查询,还是复杂的多条件组合,WordPress 都提供了完善的解决方案。在实际开发中,建议根据具体需求选择合适的方法,并注意性能优化和用户体验。


湘公网安备43020002000238