Как правильно сравнивать даты в WP query_posts meta_query

4 мар. 2011 г., 20:41:33
Просмотры: 86.9K
Голосов: 40

У меня есть вызов query_posts в шаблоне WordPress. С помощью плагина More Fields я могу дать администратору сайта возможность создавать событие (пользовательский тип записи) и вводить дату в формате: YYYY/mm/dd.

Главный вопрос: какое значение я должен передавать в параметр value в массиве meta_query? В настоящее время я пытаюсь передать "date("Y/m/d h:i A")" (без кавычек), потому что, как я понимаю, это выведет текущую дату. Время суток меня не интересует, поэтому оно может быть неактуальным. В конечном итоге я пытаюсь использовать параметр compare, чтобы точно определить показ предстоящих событий и прошедших событий в разных местах на сайте. В одном другом месте мне нужно передать в параметр value массив, который выводит первый и последний день текущего месяца, ограничивая вывод событиями, происходящими в этом месяце.

<?php 
            query_posts( array( 
              'post_type'  => 'event',        // запрашивать только события
              'meta_key'    => 'event_date',  // загрузить мета-данные event_date
              'orderby'     => 'meta_value',  // сортировать по event_date
              'order'       => 'asc',         // по возрастанию, чтобы ранние события были первыми
              'posts_per_page' => '2',
              'meta_query'  => array(         // ограничить записи на основе мета-значений
                  'key'     => 'event_date',  // какие мета-данные запрашивать
                  'value'   => date("Y/m/d h:i A"),  // значение для сравнения
                  'compare' => '>=',          // метод сравнения
                  'type'    => 'DATE'         // тип данных, мы не хотим сравнивать строковые значения
                ) // конец массива meta_query
              ) // конец массива
            ); // закрытие вызова query_posts
                 ?>
0
Все ответы на вопрос 4
4
55

Я тоже работал над точно такой же задачей, и этот пост был очень полезен. Я использовал произвольные поля (Custom Fields), и вот код, который я применил для создания списка всех событий позже текущей даты. Обратите внимание на дополнительные фильтры на основе таксономий.

<?php // Получим данные, которые нам понадобятся для цикла ниже

$events = new WP_Query( 
    array(
        'post_type' => 'event', // Указываем WordPress тип записей, которые нам нужны
        'orderby' => 'meta_value', // Сортируем события по дате    
        'meta_key' => 'event-start-date', // Используем поле "дата начала", созданное через плагин "More Fields" (формат YYYY-MM-DD)
        'order' => 'ASC', // ASC - по возрастанию, DESC - по убыванию   
        'posts_per_page' => '-1', // Показываем все записи.
        'meta_query' => array( // WordPress получил все результаты, теперь возвращаем только события после сегодняшней даты
            array(
                'key' => 'event-start-date', // Проверяем поле даты начала
                'value' => date("Y-m-d"), // Устанавливаем сегодняшнюю дату (обратите внимание на одинаковый формат)
                'compare' => '>=', // Возвращаем события, дата которых больше или равна сегодняшней
                'type' => 'DATE' // Указываем WordPress, что работаем с датой
                )
            ),
        'tax_query' => array( // Возвращаем только концерты (типы событий) и события, где выступает "songs-of-ascent"
            array(
                'taxonomy' => 'event-types',
                'field' => 'slug',
                'terms' => 'concert',
                ),
            array(
                'taxonomy' => 'speakers',
                'field' => 'slug',
                'terms' => 'songs-of-ascent',
                )
            )
        )
    );
?>
17 мар. 2011 г. 18:28:29
Комментарии

почему не 'type' => 'DATE' ?

Francisco Corrales Morales Francisco Corrales Morales
24 февр. 2015 г. 01:18:45

Могу подтвердить сомнения @FranciscoCorralesMorales: необходимо указать тип 'DATE', особенно потому что мета-поля дат сохраняются не как числа, а в формате "Y-m-d" (обратите внимание на дефисы). Я отредактировал ответ Jonathan.

Marco Panichi Marco Panichi
17 февр. 2017 г. 15:39:06

Для интернационализации вы можете использовать функцию WordPress date_i18n() вместо нативной PHP функции date().

Jake Jake
2 сент. 2017 г. 01:02:41

Думаю, будет полезно уточнить формат, в котором вы храните даты событий в своем Произвольном поле, так как сравнение форматов дат, по-видимому, является ключевым моментом при настройке рабочего meta-запроса.

David Gaskin David Gaskin
17 февр. 2023 г. 04:11:35
2

Это во многом зависит от того, как ваша дата хранится в мета-значении изначально. В целом, хорошей практикой является хранение дат в MySQL в формате дат/временных меток MySQL.

Формат временных меток MySQL: Y-m-d h:i:s.

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

Для форматирования даты MySQL для отображения используйте mysql2date($format, $mysql_date). В этом случае лучше всего отображать дату в соответствии с настройками, поэтому используйте $format = get_option('date_format');.

Для сохранения даты, выбранной пользователем, вам нужно преобразовать её в формат MySQL. Самый простой (но не самый безопасный) способ — date('Y-m-d h:i:s', $unix_timestamp);. $unix_timestamp часто можно получить с помощью strtotime($user_input).

Однако strtotime() не выполняет проверку корректности данных самостоятельно, поэтому лучше написать собственную функцию преобразования.

Что касается получения диапазона месяца, вот функция, которую я использую для получения границ месяца для любой временной метки 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 );
}

Если вам нужно получить границы недели, в WordPress уже есть готовая функция: get_weekstartend($time);, которая также возвращает границы в виде массива.

Затем вы можете использовать их в аргументе meta_query, выполняя два отдельных сравнения.

4 мар. 2011 г. 21:38:55
Комментарии

Вы имели в виду "MySQL timestamps имеют формат Y-m-d G:i:s"? G:i:s - это 24-часовой формат, h:i:s - 12-часовой.

admcfajn admcfajn
11 авг. 2018 г. 04:27:24

G - это 24-часовой формат без ведущего нуля. H - 24-часовой формат с ведущим нулём. Поэтому правильный формат: Y-m-d H:i:s

Sisir Sisir
30 нояб. 2024 г. 22:53:05
0

В итоге я остановился на следующем решении. Я создал поле event-month и сравниваю данные оттуда. Спасибо за помощь

<?php 
        $event_query = new WP_Query(
        array( 
          'post_type'   => 'event',        // запрашиваем только события
          'meta_key'    => 'event-month',  // загружаем метаданные event_date
          'order_by'        => 'event_date',
          'order'       => 'asc',         // по возрастанию, чтобы более ранние события были первыми
          'meta_query'  => array(
             array(         // ограничиваем посты по мета-значениям
              'key'     => 'event-month',  // какие метаданные запрашиваем
              'value'   => date("n"),  // значение для сравнения
              'compare' => '=',          // метод сравнения
              'type'    => 'NUMERIC'         // тип данных, мы не хотим сравнивать строковые значения
            ) // meta_query это массив элементов запроса
           ) // конец массива meta_query
          ) // конец массива
        ); // закрываем вызов конструктора WP_Query

 ?>
   <?php while($event_query->have_posts()): $event_query->the_post(); //цикл для событий ?>
8 мар. 2011 г. 01:08:09
0

Ниже представлено мое решение. Я сохраняю дату в формате Y-m-d H:i (например, 2013-07-31 16:45).

  • Сортировка по дате начала события.
  • Запрос возвращает только те события, которые завершаются после текущей даты, используя meta_query.

    date_default_timezone_set('Asia/Calcutta');

Я установил часовой пояс по умолчанию для функции 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 июл. 2013 г. 13:37:43