You must change your date to an ordering like @ Krzysiek Dróżdż said or use meta_type options. I have tested with the string version.
An example of meta_type $args
is listed below. See also MySQL time variants
/*
Plugin Name: Meta Filter
Plugin URI: https://wordpress.stackexchange.com/questions/304333
*/
// ?XDEBUG_SESSION_START=304333
function wpse_304333() {
echo '<p>wpse_304333</p>';
$args = array(
'post_type' => 'my-post-type',
'meta_key' => 'my-date-as-string-yyyy-mm-dd',
'meta_value' => '2018-03-00', // before march 2018
'meta_compare' => '>',
);
$query = new WP_Query( $args );
$titles="";
while ( $query->have_posts() ) : $query->the_post();
$titles .= '<br/>' . get_the_title();
endwhile;
echo $titles;
wp_reset_postdata();
}
add_action( 'admin_notices', 'wpse_304333' );
uses an SQL containing something like
AND (
( wp_postmeta.meta_key = 'my-date-as-string-yyyy-mm-dd'
AND wp_postmeta.meta_value < '2018-03-00' )
)
Or use meta_type like
$args = array(
'post_type' => 'my-post-type',
'meta_key' => 'my-date-key',
'meta_value' => $date_value
'meta_compare' => '>',
'meta_type' => 'DATETIME'
);
which is SQL converted using CAST. You can run the SQL below to check what values are ‘cast’ properly.
SELECT meta_value, CAST(meta_value AS DATETIME)
FROM wp_postmeta
WHERE CAST(meta_value AS DATETIME) IS NOT NULL