Как использовать query_posts() с фильтром по дате для произвольного поля?
У меня есть произвольный тип записи, который использует метаполе для хранения дат.
В моем functions.php есть следующий код, который сохраняет дату начала. Формат даты, который передается в параметре формы startdate
— 2010/12/01 9:00 AM
add_action('save_post', 'save_details');
function save_details(){
global $post;
update_post_meta($post->ID, "startdate", $_POST["startdate"]);
}
Я пытаюсь вывести список всех событий с startdate
позже текущего времени.
query_posts(array(
'post_type' => array('seminar'),
'meta_key=startdate',
'meta_value='.date("Y/m/d h:i A"),
'meta_compare=>'
));
Но выводятся все события, независимо от их даты начала. Что я делаю не так?
РЕШЕНИЕ:
По какой-то причине после изменения кода на следующий, все заработало.
$args = array(
'post_type' => array('seminar'),
'showposts' => 3,
'meta_key' => 'startdate',
'meta_value' => date("Y/m/d h:i A"),
'meta_compare' => '>',
'orderby' => 'meta_value',
'order' => 'ASC'
);
$seminars = get_posts($args);
Я выберу ответ от @Rarst как принятый, потому что думаю, что у меня было несколько проблем, но его ответ лучше всего объяснил вопрос, связанный с заголовком.
@sorich87 правильно заметил, что мне следовало хранить даты как timestamp, но в итоге @Rarst был прав — если указать аргумент формата в функции date()
, который соответствует формату хранения данных в базе, то сравнение должно работать.
Спасибо всем за помощь.

Я бы преобразовал дату в timestamp перед сохранением:
add_action('save_post', 'save_details');
function save_details(){
global $post;
update_post_meta($post->ID, "startdate", strtotime($_POST["startdate"]));
}
И использовал бы текущий timestamp для сравнения:
query_posts(array(
'post_type' => array('seminar'),
'meta_key=startdate',
'meta_value='.time(),
'meta_compare=>'
));

К сожалению, этого недостаточно. Числа, отсортированные по алфавиту, располагаются как 1,11,2, а не 1,2,11. :-) На мой взгляд, действительно необходимо дополнительное поле. http://wordpress.stackexchange.com/questions/4852/post-meta-vs-seperate-database-tables/4866#4866

Вы сохраняете дату в виде форматированной строки, но функция time()
, которую вы используете для сравнения, возвращает числовую метку времени. Таким образом, вы пытаетесь сравнить два совершенно разных формата, и маловероятно, что WordPress достаточно умен, чтобы это понять.

Есть ли способ хранить дату как Date? Я думал, что единственный способ хранить пользовательские метаданные — это строка.

Ну, нет правила, что нельзя сохранять timestamp в строке. :) Я бы попробовал сначала заменить time()
на date()
в том же формате, что и ваше мета-поле. Думаю, это должно сработать.

Я попробовал заменить на date("Y/m/d h:i A"). Это, кажется, не дало никакой разницы, хотя должно было.

Сохраните значение в базе данных следующим образом:
'enddate' => date('Y-m-d');
Сформируйте метазапрос следующим образом:
A. Условие:
$conArr[0] = array
(
'key'=> 'enddate',
'value' => date('Y-m-d'),
'compare' => '>=',
);
B. Запрос:
$args = array(
'meta_query'=>$conArr ,
'post_type'=>'tournament',
'orderby' => 'meta_value_num',
)
Важно: 'orderby' => 'meta_value_num',
и формат даты имеют значение.
