Cómo usar query_posts() con un filtro de fecha en un campo personalizado
Tengo un tipo de publicación personalizada que usa un campo meta para almacenar fechas.
En mi functions.php tengo el siguiente código que guarda la fecha de inicio. El formato de la fecha que se envía en el parámetro del formulario startdate
es 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"]);
}
Estoy intentando mostrar una lista de todos los eventos con una startdate
posterior a la hora actual.
query_posts(array(
'post_type' => array('seminar'),
'meta_key=startdate',
'meta_value='.date("Y/m/d h:i A"),
'meta_compare=>'
));
Esto muestra todos los eventos sin importar su fecha de inicio. ¿Qué estoy haciendo mal?
SOLUCIONADO:
Por alguna razón, después de cambiar mi código al siguiente, simplemente funciona.
$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);
Voy a seleccionar la respuesta de @Rarst como la aceptada, porque creo que en realidad tenía varios problemas aquí, pero la suya abordó mejor el problema relacionado con el título.
@sorich87 tenía un buen punto sobre cómo debería haber almacenado las fechas como timestamps, pero al final, @Rarst tenía razón: si especificaba un argumento de formato en la función date()
que coincidiera con el formato que usé al almacenar los datos en la base de datos, entonces debería poder comparar los datos.
Gracias por toda la ayuda.

Convertiría la fecha a una marca de tiempo antes de almacenarla:
add_action('save_post', 'save_details');
function save_details(){
global $post;
update_post_meta($post->ID, "startdate", strtotime($_POST["startdate"]));
}
Y usaría la marca de tiempo actual para hacer la comparación:
query_posts(array(
'post_type' => array('seminar'),
'meta_key=startdate',
'meta_value='.time(),
'meta_compare=>'
));

Lamentablemente, eso no es suficiente. Los números ordenados alfabéticamente se ordenan como 1,11,2 en lugar de 1,2,11. :-) Lo que realmente se necesita es un campo adicional en mi opinión. http://wordpress.stackexchange.com/questions/4852/post-meta-vs-seperate-database-tables/4866#4866

Almacenas la fecha como una cadena formateada, pero la función time()
que usas para la comparación devuelve una marca de tiempo numérica. Así que estás intentando hacer una comparación entre dos formatos completamente diferentes y es poco probable que WordPress sea lo suficientemente inteligente para entenderlo.

¿Hay alguna manera de almacenar la fecha como un Date? Pensé que la única forma de almacenar metadatos personalizados era como cadena.

Bueno, no hay ninguna regla que diga que no puedes guardar un timestamp en una cadena. :) Yo intentaría primero reemplazar time()
con date()
en el mismo formato que tu campo meta. Creo que debería funcionar de esa manera.

Intenté cambiarlo para usar date("Y/m/d h:i A"). Eso no pareció hacer ninguna diferencia aunque creo que debería haberlo hecho.

Guardar valor en la base de datos como:
'enddate' => date('Y-m-d');
Generar meta query como:
A. Condición:
$conArr[0] = array
(
'key'=> 'enddate',
'value' => date('Y-m-d'),
'compare' => '>=',
);
B. Consulta:
$args = array(
'meta_query'=>$conArr ,
'post_type'=>'tournament',
'orderby' => 'meta_value_num',
)
Importante: 'orderby' => 'meta_value_num',
y el formato de fecha son importantes.
