¿Cuál es la forma correcta de comparar fechas en una meta_query de query_posts en WordPress?

4 mar 2011, 20:41:33
Vistas: 86.9K
Votos: 40

Tengo una llamada query_posts en una plantilla de WordPress. A través del uso del plugin More Fields, puedo darle al administrador del sitio la capacidad de crear un evento (tipo de post personalizado) y luego ingresar una fecha que está formateada como: AAAA/mm/dd.

La pregunta principal es: ¿qué valor debería pasar a la opción value en el array meta_query? Actualmente estoy intentando pasar "date("Y/m/d h:i A")" (sin las comillas), porque, según tengo entendido, eso imprimirá la fecha actual de hoy. No me importa la hora del día, así que eso puede ser irrelevante. Finalmente, estoy tratando de usar la opción compare para precisar la visualización de eventos próximos y eventos pasados en diferentes lugares del sitio. En otro lugar, realmente necesito pasar a la opción value un array que imprima el primer y último día del mes actual, limitando la salida a eventos que ocurren este mes.

<?php 
            query_posts( array( 
              'post_type'  => 'event',        // consultar solo eventos
              'meta_key'    => 'event_date',  // cargar el meta event_date
              'orderby'     => 'meta_value',  // ordenar por event_date
              'order'       => 'asc',         // ascendente, eventos más antiguos primero
              'posts_per_page' => '2',
              'meta_query'  => array(         // restringir posts basados en valores meta
                  'key'     => 'event_date',  // qué meta consultar
                  'value'   => date("Y/m/d h:i A"),  // valor para comparación
                  'compare' => '>=',          // método de comparación
                  'type'    => 'DATE'         // tipo de dato, no queremos comparar valores de cadena
                ) // fin del array meta_query
              ) // fin del array
            ); // cierre de la llamada query_posts
                 ?>
0
Todas las respuestas a la pregunta 4
4
55

Terminé trabajando exactamente en lo mismo y esta publicación fue muy útil. Utilicé Campos Personalizados y aquí está el código que usé para crear una lista de todos los eventos posteriores a la fecha actual. Observa los filtros adicionales basados en taxonomías.

<?php // Obtengamos los datos que necesitamos para iterar a continuación

$events = new WP_Query( 
    array(
        'post_type' => 'event', // Indicamos a WordPress qué tipo de publicación queremos
        'orderby' => 'meta_value', // Queremos organizar los eventos por fecha    
        'meta_key' => 'event-start-date', // Obtenemos el campo "fecha de inicio" creado mediante el plugin "More Fields" (almacenado en formato YYYY-MM-DD)
        'order' => 'ASC', // ASC es la otra opción    
        'posts_per_page' => '-1', // Mostremos todos.   
        'meta_query' => array( // WordPress tiene todos los resultados, ahora, devuelve solo los eventos posteriores a la fecha actual
            array(
                'key' => 'event-start-date', // Verificamos el campo de fecha de inicio
                'value' => date("Y-m-d"), // Establecemos la fecha de hoy (nota el formato similar)
                'compare' => '>=', // Devuelve los que son posteriores a la fecha actual
                'type' => 'DATE' // Indicamos a WordPress que estamos trabajando con fechas
                )
            ),
        'tax_query' => array( // Devuelve solo conciertos (tipos de eventos) y eventos donde "songs-of-ascent" esté actuando
            array(
                'taxonomy' => 'event-types',
                'field' => 'slug',
                'terms' => 'concert',
                ),
            array(
                'taxonomy' => 'speakers',
                'field' => 'slug',
                'terms' => 'songs-of-ascent',
                )
            )
        )
    );
?>
17 mar 2011 18:28:29
Comentarios

¿por qué no 'type' => 'DATE'?

Francisco Corrales Morales Francisco Corrales Morales
24 feb 2015 01:18:45

Puedo confirmar las dudas de @FranciscoCorralesMorales: hay que especificar el tipo 'DATE', especialmente porque los campos meta de fecha no se guardan como números sino en formato "Y-m-d" (nota los guiones). He editado la respuesta de Jonathan.

Marco Panichi Marco Panichi
17 feb 2017 15:39:06

Para internacionalización, quizás quieras usar la función de WordPress date_i18n(), en lugar de la nativa de PHP date().

Jake Jake
2 sept 2017 01:02:41

Creo que sería útil especificar el formato en el que almacenas las fechas de los eventos en tu Campo Personalizado, ya que comparar formatos de fecha parece ser la pieza clave para configurar una consulta meta funcional.

David Gaskin David Gaskin
17 feb 2023 04:11:35
2

Depende en gran medida de cómo esté almacenada tu fecha en el valor meta en primer lugar. En general, es una buena idea almacenar fechas en MySQL como fechas/marcas de tiempo de MySQL.

Las marcas de tiempo de MySQL tienen el formato Y-m-d h:i:s.

Sin embargo, siempre es una buena idea usar las propias funciones de manipulación de fechas de WP. Por lo tanto, para obtener la fecha actual en formato MySQL, usa current_time('mysql').

Para formatear una fecha MySQL para mostrarla, usa mysql2date($formato, $fecha_mysql). En este caso, es mejor mostrar la fecha como está configurada en los ajustes, así que usa $formato = get_option('date_format');.

Para almacenar una fecha seleccionada por el usuario, tendrás que transcodificarla a una fecha MySQL. Para hacerlo, la forma más fácil -pero no la más segura- es date('Y-m-d h:i:s', $marca_tiempo_unix);. $marca_tiempo_unix a menudo se puede derivar mediante strtotime($entrada_usuario).

Sin embargo, strtotime() no realiza comprobaciones de validez por sí sola, por lo que es mejor escribir tu propia función de conversión.

En cuanto a obtener el rango del mes, aquí hay una función que uso para obtener los límites del mes para cualquier marca de tiempo 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 );
}

Si quieres obtener los límites de la semana, WP ya incluye una función para eso: get_weekstartend($time);, que también devuelve los límites como un array.

Luego puedes usar estos en tu argumento meta_query haciendo dos comparaciones separadas.

4 mar 2011 21:38:55
Comentarios

¿No quisiste decir "Los timestamps de MySQL tienen el formato Y-m-d G:i:s"? G:i:s es formato de 24 horas, h:i:s es de 12 horas.

admcfajn admcfajn
11 ago 2018 04:27:24

G es formato de 24 horas sin cero inicial. H es formato de 24 horas con cero inicial. Por lo tanto, es Y-m-d H:i:s

Sisir Sisir
30 nov 2024 22:53:05
0

Terminé optando por lo siguiente. Configuré un campo event-month y comparé a partir de ahí. Gracias por la ayuda.

<?php 
        $event_query = new WP_Query(
        array( 
          'post_type'   => 'event',        // solo consultar eventos
          'meta_key'    => 'event-month',  // cargar el meta event_date
          'order_by'    => 'event_date',
          'order'       => 'asc',         // ascendente, eventos más tempranos primero
          'meta_query'  => array(
             array(         // restringir posts basado en valores meta
              'key'     => 'event-month',  // qué meta consultar
              'value'   => date("n"),  // valor para comparación
              'compare' => '=',          // método de comparación
              'type'    => 'NUMERIC'         // tipo de dato, no queremos comparar valores string
            ) // meta_query es un array de elementos de consulta
           ) // fin del array meta_query
          ) // fin del array
        ); // cierre de la llamada al constructor WP_Query

 ?>
   <?php while($event_query->have_posts()): $event_query->the_post(); //bucle para eventos ?>
8 mar 2011 01:08:09
0

A continuación, comparto mi solución. Donde he almacenado las fechas en formato Y-m-d H:i (como 2013-07-31 16:45).

  • Ordenado según la fecha de inicio del Evento.
  • Solo se consultarán los Eventos que finalizan después de Hoy mediante meta_query.

    date_default_timezone_set('Asia/Calcutta');

Establezco la zona horaria predeterminada para la función 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();
30 jul 2013 13:37:43