Как правильно сравнивать даты в WP query_posts meta_query
У меня есть вызов query_posts в шаблоне WordPress. С помощью плагина More Fields я могу дать администратору сайта возможность создавать событие (пользовательский тип записи) и вводить дату в формате: YYYY/mm/dd.
Главный вопрос: какое значение я должен передавать в параметр value в массиве meta_query? В настоящее время я пытаюсь передать "date("Y/m/d h:i A")" (без кавычек), потому что, как я понимаю, это выведет текущую дату. Время суток меня не интересует, поэтому оно может быть неактуальным. В конечном итоге я пытаюсь использовать параметр compare, чтобы точно определить показ предстоящих событий и прошедших событий в разных местах на сайте. В одном другом месте мне нужно передать в параметр value массив, который выводит первый и последний день текущего месяца, ограничивая вывод событиями, происходящими в этом месяце.
<?php
query_posts( array(
'post_type' => 'event', // запрашивать только события
'meta_key' => 'event_date', // загрузить мета-данные event_date
'orderby' => 'meta_value', // сортировать по event_date
'order' => 'asc', // по возрастанию, чтобы ранние события были первыми
'posts_per_page' => '2',
'meta_query' => array( // ограничить записи на основе мета-значений
'key' => 'event_date', // какие мета-данные запрашивать
'value' => date("Y/m/d h:i A"), // значение для сравнения
'compare' => '>=', // метод сравнения
'type' => 'DATE' // тип данных, мы не хотим сравнивать строковые значения
) // конец массива meta_query
) // конец массива
); // закрытие вызова query_posts
?>
Я тоже работал над точно такой же задачей, и этот пост был очень полезен. Я использовал произвольные поля (Custom Fields), и вот код, который я применил для создания списка всех событий позже текущей даты. Обратите внимание на дополнительные фильтры на основе таксономий.
<?php // Получим данные, которые нам понадобятся для цикла ниже
$events = new WP_Query(
array(
'post_type' => 'event', // Указываем WordPress тип записей, которые нам нужны
'orderby' => 'meta_value', // Сортируем события по дате
'meta_key' => 'event-start-date', // Используем поле "дата начала", созданное через плагин "More Fields" (формат YYYY-MM-DD)
'order' => 'ASC', // ASC - по возрастанию, DESC - по убыванию
'posts_per_page' => '-1', // Показываем все записи.
'meta_query' => array( // WordPress получил все результаты, теперь возвращаем только события после сегодняшней даты
array(
'key' => 'event-start-date', // Проверяем поле даты начала
'value' => date("Y-m-d"), // Устанавливаем сегодняшнюю дату (обратите внимание на одинаковый формат)
'compare' => '>=', // Возвращаем события, дата которых больше или равна сегодняшней
'type' => 'DATE' // Указываем WordPress, что работаем с датой
)
),
'tax_query' => array( // Возвращаем только концерты (типы событий) и события, где выступает "songs-of-ascent"
array(
'taxonomy' => 'event-types',
'field' => 'slug',
'terms' => 'concert',
),
array(
'taxonomy' => 'speakers',
'field' => 'slug',
'terms' => 'songs-of-ascent',
)
)
)
);
?>

Могу подтвердить сомнения @FranciscoCorralesMorales: необходимо указать тип 'DATE', особенно потому что мета-поля дат сохраняются не как числа, а в формате "Y-m-d" (обратите внимание на дефисы). Я отредактировал ответ Jonathan.

Для интернационализации вы можете использовать функцию WordPress date_i18n()
вместо нативной PHP функции date()
.

Это во многом зависит от того, как ваша дата хранится в мета-значении изначально. В целом, хорошей практикой является хранение дат в MySQL в формате дат/временных меток MySQL.
Формат временных меток MySQL: Y-m-d h:i:s
.
Однако всегда рекомендуется использовать собственные функции работы с датами в WordPress. Например, чтобы получить текущую дату в формате MySQL, используйте current_time('mysql')
.
Для форматирования даты MySQL для отображения используйте mysql2date($format, $mysql_date)
.
В этом случае лучше всего отображать дату в соответствии с настройками, поэтому используйте $format = get_option('date_format');
.
Для сохранения даты, выбранной пользователем, вам нужно преобразовать её в формат MySQL. Самый простой (но не самый безопасный) способ — date('Y-m-d h:i:s', $unix_timestamp);
. $unix_timestamp
часто можно получить с помощью strtotime($user_input)
.
Однако strtotime()
не выполняет проверку корректности данных самостоятельно, поэтому лучше написать собственную функцию преобразования.
Что касается получения диапазона месяца, вот функция, которую я использую для получения границ месяца для любой временной метки MySQL:
function get_monthrange($time) {
$ym = date("Y-m", strtotime($time));
$start = $ym."-01";
$ym = explode("-", $ym);
if ($ym[1] == 12) {
$ym[0]++; $ym[1] = 1;
} else {
$ym[1]++;
}
$d = mktime( 0, 0, 0, $ym[1], 1, $ym[0] );
$d -= 86400;
$end = date("Y-m-d", $d);
return array( $start, $end );
}
Если вам нужно получить границы недели, в WordPress уже есть готовая функция: get_weekstartend($time);
, которая также возвращает границы в виде массива.
Затем вы можете использовать их в аргументе meta_query
, выполняя два отдельных сравнения.

Вы имели в виду "MySQL timestamps имеют формат Y-m-d G:i:s
"? G:i:s
- это 24-часовой формат, h:i:s
- 12-часовой.

В итоге я остановился на следующем решении. Я создал поле event-month и сравниваю данные оттуда. Спасибо за помощь
<?php
$event_query = new WP_Query(
array(
'post_type' => 'event', // запрашиваем только события
'meta_key' => 'event-month', // загружаем метаданные event_date
'order_by' => 'event_date',
'order' => 'asc', // по возрастанию, чтобы более ранние события были первыми
'meta_query' => array(
array( // ограничиваем посты по мета-значениям
'key' => 'event-month', // какие метаданные запрашиваем
'value' => date("n"), // значение для сравнения
'compare' => '=', // метод сравнения
'type' => 'NUMERIC' // тип данных, мы не хотим сравнивать строковые значения
) // meta_query это массив элементов запроса
) // конец массива meta_query
) // конец массива
); // закрываем вызов конструктора WP_Query
?>
<?php while($event_query->have_posts()): $event_query->the_post(); //цикл для событий ?>

Ниже представлено мое решение. Я сохраняю дату в формате Y-m-d H:i
(например, 2013-07-31 16:45).
- Сортировка по дате начала события.
Запрос возвращает только те события, которые завершаются после текущей даты, используя
meta_query
.date_default_timezone_set('Asia/Calcutta');
Я установил часовой пояс по умолчанию для функции date()
.
$args = array(
'posts_per_page' => 3,
'orderby' => 'meta_value',
'meta_key' => 'event_start_date_time',
'order' => 'ASC',
'post_type' => 'events',
'meta_query' => array(
array(
'key' => 'event_end_date_time',
'value' => date("Y-m-d H:i"),
'compare' => '>=',
'type' => 'DATE'
)
)
);
query_posts( $args );
if( have_posts() ) : while ( have_posts() ) : the_post();
