How to use query_posts() with a date filter on a custom field?

I have defined a custom post type that uses a meta field to store dates.

In my functions.php I have the following code which saves the start date. The format of the date that is sent in the startdate form parameter is 2010/12/01 9:00 AM

Read More
add_action('save_post', 'save_details');

function save_details(){
    global $post;
    update_post_meta($post->ID, "startdate", $_POST["startdate"]);
}

I am trying to output a list of all the events with a startdate later than the current time.

query_posts(array(
    'post_type' => array('seminar'),
    'meta_key=startdate',
    'meta_value='.date("Y/m/d h:i A"),
    'meta_compare=>'
));

This lists out all the events regardless of their start date. What am I doing wrong?

SOLVED:

For some reason after I changed my code to the following, it just works.

$args = array(
    'post_type' => array('seminar'),
    'showposts' => 3,
    'meta_key' => 'startdate',
    'meta_value' => date("Y/m/d h:i A"),
    'meta_compare' => '>',
    'orderby' => 'meta_value',
    'order' => 'ASC'
);

$seminars = get_posts($args);

I am going to select the answer from @Rarst as the accepted one, because I think I actually had multiple issues going on here, but his addressed the issue related to the title best.

@sorich87 had a good point about how I should have been storing the dates as timestamps, but in the end, @Rarst was correct that if I specified a format argument to the date() function which matches the format I used when storing the data into the database, then I should be able to compare the data.

Thanks for all the help.

Related posts

Leave a Reply

4 comments

  1. You store date as formatted string, but time() function you take for comparison returns numeric timestamp. So you are trying to make comparison between too completely different formats and it’s unlikely WP is smart enough to get that.

  2. I would convert the date to a timestamp before storing it:

    add_action('save_post', 'save_details');
    
    function save_details(){
        global $post;
        update_post_meta($post->ID, "startdate", strtotime($_POST["startdate"]));
    }
    

    And use the current timestamp to do the comparison:

    query_posts(array(
        'post_type' => array('seminar'),
        'meta_key=startdate',
        'meta_value='.time(),
        'meta_compare=>'
    ));
    
  3. Perhaps this would do the trick?

    query_posts(array(
        'post_type' => array('seminar'),
        'meta_key' => 'startdate',
        'orderby'=> 'meta_value',
        'order' => 'ASC'
    ));
    
    1. Save value in database like :

      'enddate'   =>  date('Y-m-d');
      
    2. Generate meta query like :

    A. Condition :

    $conArr[0]  =    array
    (
    'key'=> 'enddate',
    'value' => date('Y-m-d'),
    'compare' => '>=',
    );
    

    B. Query:

    $args = array(
        'meta_query'=>$conArr ,
        'post_type'=>'tournament',
        'orderby' => 'meta_value_num', 
    )
    

    Important 'orderby' => 'meta_value_num', and date format are important.