Ошибка сравнения дат в meta_query WordPress
Вот фрагмент кода, который я использую для получения записей событий, чья дата в метаполях новее сегодняшней:
<?php
query_posts( array(
'post_type' => 'concerts', // Тип записи - концерты
'meta_key' => 'numericdate', // Метаполе с датой
'posts_per_page' => -1, // Все записи
'orderby' => 'meta_value', // Сортировка по значению метаполя
'order' => 'ASC', // По возрастанию
'meta_query' => array(
array(
'key' => 'numericdate', // Ключ метаполя
'value' => date('dmY'), // Текущая дата
'compare' => '>=', // Сравнение "больше или равно"
'type' => 'date' // Тип сравнения - дата
)
)
) );
if (have_posts()) : ?>
Этот запрос не возвращает никаких результатов. Поле "numericdate" содержит строку в формате "ddmmyyyy", поэтому я ожидал, что сравнение с текущей датой в формате "dmY" будет работать. Я ошибался. Либо в приведенном коде есть какая-то ошибка. Спасибо за помощь!

У меня точно такая же проблема, только я использую стандартный тип записи (post) и категорию в своем запросе. Все работает, кроме порядка сортировки.
$d = date("Y-m-d");
$args = array(
'post_type' => 'post',
'category_name' => 'events',
'post_status' => 'publish,draft,pending,future,private', // только для меня
'meta_key' => 'event_start',
'orderby' => 'meta_value_num',
'order' => 'ASC',
'posts_per_page' => -1,
'meta_query' => array(
array(
'key' => 'event_start',
'value' => $d,
'type' => 'date',
'compare' => '>'
)
)
);
Но мои записи все равно сортируются как строки. Что я сделал не так?
После некоторых проб и ошибок я обнаружил, что вместо 'meta_value_num' нужно было использовать 'meta_value':
$d = date("Y-m-d");
$args = array(
'post_type' => 'post',
'category_name' => 'events',
'post_status' => 'publish,draft,pending,future,private',
'meta_key' => 'event_start',
'orderby' => 'meta_value',
'order' => 'ASC',
'posts_per_page' => -1,
'meta_query' => array(
array(
'key' => 'event_start',
'value' => $d,
'type' => 'date',
'compare' => '>'
)
)
);

Для справки, используйте WordPress функцию current_time() для подобных запросов.
current_time('mysql')
возвращает серверное время согласно настройкам администратора в формате, приемлемом для MySQL

Действительно, операция CAST()
вернет NULL
, если ваши данные имеют неправильный формат. Она также принимает формат YYYYMMDD
без разделителей, но не DDMMYYYY
. Я не уверен насчет orderby
- будет ли он использовать преобразованные значения из мета-запроса?

Спасибо, Мило, теперь всё работает отлично! meta_value_num
справился с задачей, интересно почему никто не заметил эту деталь в похожей теме: http://bit.ly/l88vup

Несмотря на предпочтения MySQL к форматам даты, есть много веских причин использовать форматы с обратным порядком (big-endian), такие как Y-m-d.
Можно подумать, что сравнение дат — это очевидный процесс, но...
05262011 > 01012012
и так далее. Вы создадите себе множество проблем, пытаясь использовать формат dmY.
Кроме того, я не думаю, что 'date' является одним из допустимых параметров для "type" в meta_query. Лучше опустить этот параметр и использовать строковое сравнение для получения наилучших результатов.

дата является допустимой, из записи WP_Query в codex: Возможные значения: 'NUMERIC', 'BINARY', 'CHAR', 'DATE', 'DATETIME', 'DECIMAL', 'SIGNED', 'TIME', 'UNSIGNED'. Значение по умолчанию: 'CHAR'.

Если у кого-то возникла такая же проблема, лучше обратиться к фильтру posts_clauses.
Он позволяет напрямую манипулировать SQL-запросом.
С его помощью можно преобразовать значение колонки с датой и изменить условия WHERE и ORDERBY.
$pieces['where'] .= " AND STR_TO_DATE(wp_postmeta.meta_value,'%d%m%Y' ) >=
CURRENT_DATE() ";
$pieces['orderby'] = "STR_TO_DATE( wp_postmeta.meta_value,'%d%m%Y' ) DESC";
