Custom query, checking values of multiple meta keys

You can use meta_query to combine multiple queries using either AND or OR relation. Granted, it does get a bit complex in this case, but because you can nest multiple queries, you can still achieve it.

This is covered in the WP_Meta_Query documentation and also to an extent in the WP_Query docs.

Here’s what I think should work. I haven’t tested this, but it should do what you want: compare these three fields to make sure the event is in the past.

Scroll below the code for an explanation of what it’s doing.

$query['meta_query'] = array(
  'relation' => 'OR',
  array(
    'key' => 'pec_end_datetime',
    'compare' => '<',
    'value' => current_time('Y-m-d'),
    'type' => 'DATE',
  ),
  array(
    'relation' => 'AND',
    array(
      'key' => 'pec_end_datetime',
      'compare' => '=',
      'value' => current_time('Y-m-d'),
      'type' => 'DATE',
    ),
    array(
      'key' => 'pec_end_time_hh',
      'compare' => '<',
      'value' => current_time('G'),
      'type' => 'NUMERIC',
    ),
  ),
  array(
    'relation' => 'AND',
    array(
      'key' => 'pec_end_datetime',
      'compare' => '=',
      'value' => current_time('Y-m-d'),
      'type' => 'DATE',
    ),
    array(
      'key' => 'pec_end_time_hh',
      'compare' => '=',
      'value' => current_time('G'),
      'type' => 'NUMERIC',
    ),
    array(
      'key' => 'pec_end_time_mm',
      'compare' => '<',
      'value' => current_time('i'),
      'type' => 'NUMERIC',
    ),
  ),
);

What we’re doing is providing three different meta_queries with an OR relation. If any of them are true, the event is in the past:

  • if the date is less than today’s date, OR
  • if the date is today AND the hour is less than the current hour, OR
  • if the date is today, AND the hour is the current hour, AND the minute is less than the current minute

Unfortunately we can’t combine all of these into one simple query, because we obviously don’t want an event three hours in the future, at half past the hour, to come up as a past event when it’s 45 minutes into the current hour!

The strings sent to current_time() all match the PHP date formats.