Support

Account

Home Forums General Issues wp_query how to order events by date then time

Solved

wp_query how to order events by date then time

  • I’m using ACF to build an events calendar and I was hoping for some help with ordering the events by its date then by a separate field for its time (I can’t switch to the date & time picker).

    The calendar has 5 relevant fields in use for this question.

    • Start Date
    • End Date
    • Start Time
    • End Time
    • All Day Event

    I’m currently ordering the events by start and end date using the code below.

      
    $today = date('Ymd');
    
    $events_args = array(
        'post_type' => 'events',
        'post_status' => 'publish',
        'posts_per_page' => -1,
        'meta_query' => [
          [
            'relation' => 'AND',
            [
                'relation' => 'OR',
                [
                  'key'		=> 'start_date',
                  'compare'	=> '>',
                  'value'		=> $today,
                ],
                [
                  'key'		=> 'end_date',
                  'compare'	=> '>',
                  'value'		=> $today,
                ]
            ]
          ]
        ],
        'meta_key' => 'start_date',
        'orderby' => 'meta_value',
        'order' => 'ASC'
      );
    
    $events = new WP_Query($events_args);
    

    But I want to then also order the events by start time as events are occasionally loading 1 December 1pm – 3pm – 1 December 9am – 12pm.

    As you can see the 2nd events time is before the first events because they’re not also being ordered by start time.

    Another factor in the mix is the fact that start and end time are optional as I’ve given the option of all day event.

    I appreciate this is a complex use case for wp_query but I’d really appreciate any help and thank you in advance.

  • I can see in a forum post below that using clauses might be the way forward but as you can see from the below example

    'meta_query' => array(
    	'relation' => 'AND',
        'date_clause' => array(
            'key' => 'event_date',
    		'compare'	=> '=',
        ),
        'time_clause' => array(
            'key' => 'event_time',
    		'compare'	=> '=',
        ),
    ),
    'orderby' => array(
    	'date_clause' => 'ASC',
    	'time_clause' => 'ASC',
    ),
    

    Which I’ve borrowed from that post is that my needs include an OR relation for start and end date (end date like start and end time are also optional) so can a clause include an OR relation inside of it or is there a different way to solve this?

  • Ok, so I’ve solved this but not by using meta_query but by sorting the array of events after the query.

    I added a new entry to my events array called “datetime”.

        if( get_field('all_day_event', $event_item->ID) != true ):
    
          $events[$i]['datetime'] = date_format($start_date, "Y-m-d") . ' ' . get_field('start_time', $event_item->ID);
    
          $events[$i]['time'] = get_field('start_time', $event_item->ID) . ( get_field('end_time', $event_item->ID) ? ' - ' . get_field('end_time', $event_item->ID) : '' );
    
        else:
    
          $events[$i]['datetime'] = date_format($start_date, "Y-m-d") . ' 0:00';
    
          $events[$i]['time'] = null;
    
        endif;

    I then sorted the events array by using the below.

      $compare_function = function($a,$b) {
        $a_timestamp = strtotime($a['datetime']); // convert a (string) date/time to a (int) timestamp
        $b_timestamp = strtotime($b['datetime']);
            // new feature in php 7
        return $a_timestamp <=> $b_timestamp;
      };
    
      usort($events, $compare_function);
Viewing 3 posts - 1 through 3 (of 3 total)

You must be logged in to reply to this topic.