Qual è il modo corretto per confrontare le date in una WP query_posts meta_query
Ho una chiamata query_posts in un template WP. Attraverso l'uso del plugin More Fields posso dare all'amministratore del sito la possibilità di creare un evento (custom post type) e quindi inserire una data che viene formattata: YYYY/mm/dd.
La domanda principale è: quale valore dovrei passare all'opzione value nell'array meta_query? Attualmente sto cercando di passare "date("Y/m/d h:i A")" (senza le virgolette), perché, per come lo capisco, stamperà la data corrente di oggi. Non mi interessa l'ora quindi potrebbe essere irrilevante. Fondamentalmente sto cercando di utilizzare l'opzione compare per definire la visualizzazione di eventi futuri ed eventi passati in diverse parti di questo sito. In un altro punto ho effettivamente bisogno di passare all'opzione value un array che stampi il primo e l'ultimo giorno del mese corrente, limitando l'output agli eventi che si verificano questo mese.
<?php
query_posts( array(
'post_type' => 'event', // interroga solo gli eventi
'meta_key' => 'event_date', // carica il meta event_date
'orderby' => 'meta_value', // ordina per event_date
'order' => 'asc', // ascendente, quindi prima gli eventi più vecchi
'posts_per_page' => '2',
'meta_query' => array( // limita i post basati sui valori meta
'key' => 'event_date', // quale meta interrogare
'value' => date("Y/m/d h:i A"), // valore per il confronto
'compare' => '>=', // metodo di confronto
'type' => 'DATE' // tipo di dati, non vogliamo confrontare i valori stringa
) // fine array meta_query
) // fine array
); // chiude la chiamata query_posts
?>
Mi sono trovato a lavorare esattamente sulla stessa cosa e questo post è stato molto utile. Ho utilizzato i Custom Fields e questo è il codice che ho usato per creare un elenco di tutti gli eventi successivi alla data corrente. Nota i filtri aggiuntivi basati sulle tassonomie.
<?php // Recuperiamo i dati che ci servono per il ciclo successivo
$events = new WP_Query(
array(
'post_type' => 'event', // Indichiamo a WordPress il tipo di post che vogliamo
'orderby' => 'meta_value', // Vogliamo organizzare gli eventi per data
'meta_key' => 'event-start-date', // Prendiamo il campo "data di inizio" creato tramite il plugin "More Fields" (memorizzato nel formato YYYY-MM-DD)
'order' => 'ASC', // ASC è l'altra opzione
'posts_per_page' => '-1', // Mostriamoli tutti.
'meta_query' => array( // WordPress ha tutti i risultati, ora restituiamo solo gli eventi dopo la data odierna
array(
'key' => 'event-start-date', // Controlliamo il campo data di inizio
'value' => date("Y-m-d"), // Impostiamo la data odierna (nota il formato simile)
'compare' => '>=', // Restituiamo quelli successivi alla data odierna
'type' => 'DATE' // Comunichiamo a WordPress che stiamo lavorando con date
)
),
'tax_query' => array( // Restituiamo solo concerti (tipi di evento) ed eventi in cui si esibisce "songs-of-ascent"
array(
'taxonomy' => 'event-types',
'field' => 'slug',
'terms' => 'concert',
),
array(
'taxonomy' => 'speakers',
'field' => 'slug',
'terms' => 'songs-of-ascent',
)
)
)
);
?>

Posso confermare i dubbi di @FranciscoCorralesMorales: devi specificare il tipo 'DATE', soprattutto perché i campi meta delle date non sono salvati come numeri ma nella forma "Y-m-d" (nota i trattini). Ho modificato la risposta di Jonathan.

Per l'internazionalizzazione, potresti voler usare la funzione di WordPress date_i18n()
, invece della funzione nativa di php date()
.

Dipende in gran parte da come la data è memorizzata nel valore meta in primo luogo. In generale, è una buona idea memorizzare le date in MySQL come date/timestamp MySQL.
I timestamp MySQL hanno il formato Y-m-d h:i:s
.
Tuttavia, è sempre una buona idea utilizzare le funzioni di gestione delle date di WP. Pertanto, per ottenere la data corrente in formato MySQL, usa current_time('mysql')
.
Per formattare una data MySQL per la visualizzazione, usa mysql2date($format, $mysql_date)
.
In questo caso è meglio visualizzare la data come configurato nelle impostazioni, quindi usa $format = get_option('date_format');
.
Per memorizzare una data selezionata dall'utente, dovrai trascodificarla in una data MySQL. Per farlo, il modo più semplice - ma non il più sicuro - è date('Y-m-d h:i:s', $unix_timestamp);
. $unix_timestamp
può spesso essere derivato tramite strtotime($user_input)
.
Tuttavia, strtotime()
non effettua controlli di validità da solo, quindi è meglio scrivere la propria funzione di conversione.
Per quanto riguarda l'ottenimento dell'intervallo mensile, ecco una funzione che uso per ottenere i limiti del mese per qualsiasi timestamp 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 );
}
Se vuoi ottenere i limiti della settimana, WP include già una funzione per questo: get_weekstartend($time);
, che restituisce anche i limiti come un array.
Puoi quindi utilizzarli nel tuo argomento meta_query
effettuando due confronti separati.

Alla fine ho optato per la seguente soluzione. Ho impostato un campo event-month e faccio il confronto da lì. Grazie per l'aiuto
<?php
$event_query = new WP_Query(
array(
'post_type' => 'event', // query solo per eventi
'meta_key' => 'event-month', // carica il meta event_date
'order_by' => 'event_date',
'order' => 'asc', // ordine ascendente, quindi eventi più recenti prima
'meta_query' => array(
array( // restringe i post basandosi sui valori meta
'key' => 'event-month', // quale meta interrogare
'value' => date("n"), // valore per il confronto
'compare' => '=', // metodo di confronto
'type' => 'NUMERIC' // tipo di dato, non vogliamo confrontare i valori come stringhe
) // meta_query è un array di elementi di query
) // fine array meta_query
) // fine array
); // chiusura della chiamata al costruttore WP_Query
?>
<?php while($event_query->have_posts()): $event_query->the_post(); //loop per gli eventi ?>

Di seguito pubblico la mia soluzione. Ho memorizzato la data nel formato Y-m-d H:i
(come 2013-07-31 16:45).
- Ordinato in base alla data di inizio dell'Evento.
Verranno interrogati solo gli Eventi che terminano dopo la data odierna tramite
meta_query
.date_default_timezone_set('Asia/Calcutta');
Ho impostato il fuso orario predefinito per la funzione 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();
