本文へ移動

トラブルシュート

WP_Queryで日付順に並ばない原因
|orderby・order・日付値を確認

「新着順にしたいのに古い記事が先に出る」「投稿日順にはなるがイベント開催日順にならない」場合は、画面に日付値を出して基準を確認します。投稿日ならdate、更新日ならmodified、ACFなどの独自日付ならmeta_keyと保存値を見ます。

Huddly Huddly 投稿日: 2026年9月7日 更新日: 2026年9月12日 読了目安: 8分

最初に「どの日付を並べたいか」を決める

WP_Queryは、投稿日、更新日、カスタムフィールドの日付で指定方法が変わります。まず実際の日付値をタイトルと一緒に表示し、並べたい値と orderby の対象が一致しているか確認してください。

投稿日は date、更新日は modified、ACFなどの独自日付は meta_key と保存形式を確認します。最初に並べたい日付を1つに決めると、確認すべき指定を取り違えません。 その後に order の向き、同日データの二次ソート、pre_get_posts やプラグインの上書きを1つずつ切り分けます。

症状から確認する日付と指定を選ぶ

投稿日時と、ACFなどで作ったイベント日・公開予定日・開催日は別のデータです。新着順、古い順、イベント日順のどれが違うかで確認先を分けます。

症状最初に疑う原因見る場所
新着順にならないorder と orderby の指定が想定と違う$args の orderby / order
古い順にしたいのに新しい順になるASC / DESC の意味を逆に覚えているorder の値
イベント日順にならない投稿日時で並べていて、ACFの日付を見ていないmeta_key / meta_value_num
一部だけ順番が入れ替わる同じ日時の投稿が複数あり、二次ソートがないorderby の複数指定
メイン一覧だけ順番が変わるpre_get_posts やテーマ側の処理が上書きしているfunctions.php / プラグイン

確認の順番

  1. 1
    投稿日時順なのか、カスタムフィールドの日付順なのかを決める
  2. 2
    orderby と order を最小構成で確認する
  3. 3
    同じ日時の投稿がないか確認する
  4. 4
    ACFなどの日付フィールドなら保存形式と meta_key を確認する
  5. 5
    pre_get_posts、プラグイン、テーマ側で並び替えが上書きされていないか確認する

投稿日時で並べる最小例

まずは投稿日時で正しく並ぶかを確認します。ここで期待どおりに並ぶなら、WP_Queryの基本的な並び替えは動いていて、原因はカスタムフィールドや別の条件にある可能性が高くなります。

次のコードは、公開済みの通常投稿を投稿日が新しい順に3件表示します。2026年9月12日時点のWP Query Builderで、投稿タイプを「post」、投稿ステータスを「publish」、件数を「3」、並び順を「DESC」、並び替えを「date」、先頭固定を無視する指定を有効にして生成した $args をそのまま使っています。比較しやすいよう、自動最適化はオフにしました。

PHPテンプレートを使う子テーマの template-parts/date-order-check.php に保存し、表示したいテンプレートのメインループで the_post() の後に get_template_part( ‘template-parts/date-order-check’ ); を置いてください。呼び出し先がすでにPHPとして実行される場所なら、呼び出しコードの前に <?php を重ねて書く必要はありません。投稿本文や追加CSSへは貼らず、確認が終わったら不要な呼び出しとファイルを外します。

原因を切り分けるための一時的な確認コードです。ローカルなどの検証環境だけで使い、確認後は削除してください。

PHPtemplate-parts/date-order-check.php投稿日時の新しい順に3件を表示する確認用パーツ
<?php$args = array(    'post_type' => 'post',    'post_status' => 'publish',    'posts_per_page' => 3,    'order' => 'DESC',    'orderby' => 'date',    'ignore_sticky_posts' => true); $the_query = new WP_Query( $args ); if ( $the_query->have_posts() ) {   echo '<ul>';   while ( $the_query->have_posts() ) {      $the_query->the_post();      echo '<li><a href="' . esc_url( get_permalink() ) . '">' . esc_html( get_the_title() ) . '</a>';      echo '<br>投稿日時:' . esc_html( get_the_date( 'Y-m-d H:i:s' ) ) . '</li>';   }   echo '</ul>';} else {   echo '<p>公開済みの投稿はありません。</p>';} wp_reset_postdata();

Builderが生成したのは $args までです。その後の new WP_Query()、日付付きの表示、0件時の文言、wp_reset_postdata() は、結果を確かめるために追加しています。DESCは新しい投稿から古い投稿、ASCは古い投稿から新しい投稿の順です。

もうひとつ大事なのは、表示する日付を一緒に出していることです。タイトルだけを見ると「並んでいない」と感じても、実際には投稿日時が同じだったり、思っていた投稿日と違う値が入っていたりすることがあります。まずは画面に日付を出して、データ側を確認してください。

ignore_sticky_posts は先頭固定の特別扱いを外す指定で、固定投稿そのものを除外する指定ではありません。同じ投稿日時がある場合の順番は、後半のIDを併用する例で固定します。

次の画像は、このコードをローカルのサンプルサイトで実行した結果です。タイトルだけでなく、並び替えに使った投稿日時も同じ画面に表示しています。

最初のPHPで表示した通常投稿3件とそれぞれの投稿日時
表示例タイトルと投稿日時を一緒に見る

本文の最初のコードで、2026年9月1日10:03→10:02→10:01の順に3件を表示しています。各タイトルの下に実際の投稿日時を出しています。

投稿の日付やコードを変える作業は、本番と分けた環境で行います。サーバー上へ試す場所を用意する場合は、XserverのPHP対応やバックアップ条件も確認できます。

ACFなどのカスタムフィールド日付で並べたい場合

投稿日時そのものを並べ替える場合は、orderbyとorderの基本を確認してください。ACF Date Pickerの保存形式と絞り込みは、ACFの日付フィールドを絞り込む方法で別に確認できます。

イベント一覧やセミナー一覧では、投稿日ではなく「開催日」で並べたいことがあります。orderby の date は投稿日時を表すため、ACFの開催日を入れても開催日順にはなりません。

ACF Date Picker のような日付フィールドで並べたい場合は、対象のフィールド名を meta_key に指定し、その値で並べます。ACFのDate Pickerは、表示形式や返り値形式とは別に、データベースには Ymd 形式で保存されると公式資料で説明されています。そのため、数値として並べるなら meta_value_num を使うと確認しやすいです。

確認する値この例の値WP_Queryでの役割
画面の表示形式2026年6月14日読者へ見せる表記
ACFの返り値形式2026-06-14get_field()で受け取る形式
データベース保存値20260614meta_queryと並び替えが比較する値

クエリで比較するのは、返り値の2026-06-14ではなく、保存値と同じYmd形式です。今日なら current_time( ‘Ymd’ ) で、WordPressのタイムゾーン設定に基づく値を作ります。

次の例は、開催日を持つ投稿タイプ works を使います。WP Query Builderには、投稿タイプ「works」、投稿ステータス「publish」、件数「10」、並び順「ASC」、並び替え「meta_value_num」を入力し、event_date が 20260801 以上になる数値条件を追加しました。生成された $args は変更していません。

実際に event として登録しているなら、post_type を event へ変更してください。template-parts/event-date-order.php に保存し、先ほどと同じ設置条件で get_template_part( ‘template-parts/event-date-order’ ); と呼びます。

クラシックテーマのテンプレート(またはテンプレートパーツ)で、一覧を表示したい位置に置く例です。投稿本文やfunctions.phpへ、そのまま貼るコードではありません。

PHPtemplate-parts/event-date-order.php2026年8月1日以降の開催日を近い順に表示する確認用パーツ
<?php$args = array(    'post_type' => 'works',    'post_status' => 'publish',    'posts_per_page' => 10,    'order' => 'ASC',    'orderby' => 'meta_value_num',    'meta_query' => array(        array(            'key' => 'event_date',            'compare' => '>=',            'type' => 'NUMERIC',            'value' => 20260801        )    ),    'meta_key' => 'event_date'); $event_query = new WP_Query( $args ); if ( $event_query->have_posts() ) {   echo '<ul>';   while ( $event_query->have_posts() ) {      $event_query->the_post();      echo '<li><a href="' . esc_url( get_permalink() ) . '">' . esc_html( get_the_title() ) . '</a>';      echo '<br>開催日(保存値):' . esc_html( get_post_meta( get_the_ID(), 'event_date', true ) ) . '</li>';   }   echo '</ul>';} else {   echo '<p>条件に合う開催予定はありません。</p>';} wp_reset_postdata();

このコードでは、event_dateを並び替え対象にし、保存値が 20260801 以上の投稿だけに絞っています。Builderが生成したのは $args までで、表示ループと0件時の文言、リセットは手動で追加しています。

実運用で「今日以降」にする場合は、生成コードの 20260801 だけを (int) current_time( ‘Ymd’ ) へ置き換えます。動的な今日の日付はBuilderの入力値ではなく、WordPressのタイムゾーンを使うために手動で加える部分です。 同じ開催日の順番まで固定したい場合は、後半の複数指定と同じ考え方で二次ソートを追加します。

つまずきやすいのは、ACFの「表示形式」や「返り値形式」を見て、保存値も同じだと思ってしまうことです。実際にWP_Queryが比較するのは、データベースに保存されているpost metaです。画面表示の2026年6月14日、返り値の2026-06-14、保存値の20260614を別々に確認してください。

次の実画面では、フィールド名と2つの表示設定を確認できます。保存値は画面の表示形式とは別なので、記事内の一覧では get_post_meta() の値も併記します。

匿名の検証環境にあるACF Date Pickerのフィールド名、表示形式、返り値形式
ACF Date Picker表示形式・返り値・保存値を分けて確認

フィールド名はevent_date、画面表示はY年m月d日、返り値はY-m-dです。WP_Queryが比較するデータベース保存値はYmd形式です。

同じ保存値で、日付の下限と並び順を見る

次の画像では、保存値が 20260712・20260812・20260905 の3件に、上のBuilder生成コードをそのまま実行しました。8月12日、9月5日の順になり、7月12日は対象から外れます。

2026年8月1日以降の条件で、夏の制作相談会20260812、秋のWP_Query勉強会20260905の順に並ぶサイト
開催日の表示例基準日以降を、開催日の近い順に並べる

基準日を20260801に固定した例です。対象2件は20260812→20260905の順。実運用では値をcurrent_time('Ymd')へ置き換え、日付経過で対象が減ることも確認します。

この3件だけなら、2026年9月6日以降は0件です。「条件に合う開催予定はありません」と出るのは日付条件に合う投稿がないためで、並び替えの失敗ではありません。日付未保存や空文字の投稿も、この数値の下限条件には入りません。

原因ごとの切り分けポイント

表示件数を3件程度にし、日付値を画面へ出します。post_type、meta_query、tax_query、ページネーション、並び順は1つずつ戻してください。

1. ASC と DESC の向きを逆に覚えている

ASC は小さい値から大きい値へ、DESC は大きい値から小さい値へ並べます。日付の場合、新しい日付ほど値が大きくなるため、新着順は基本的に DESC、古い順は ASC です。

イベント日順では少し感覚が変わります。今日以降のイベントを近い順に表示したい場合は、過去日を除外したうえで ASC にします。過去日を除外しないまま ASC にすると、古いイベントが先頭に出て「近い順になっていない」と感じることがあります。

2. 並べたい日付と orderby の対象が違う

orderby => ‘date’ は投稿日時、orderby => ‘modified’ は更新日時です。イベント日や締切日など、独自に作った日付フィールドではありません。

date_queryは投稿日時などを期間で絞り込むための指定で、並び替え基準を選ぶorderbyの代わりにはなりません。「今年の記事だけを新しい順にする」なら、date_queryで対象期間を絞り、orderby => ‘date’とorder => ‘DESC’で順番を決めます。

カスタムフィールドの日付で並べるなら、meta_key と orderby => ‘meta_value’ または meta_value_num を使います。日付の保存形式によって向いている指定が変わるため、まずは実際の保存値を get_post_meta() で表示して確認してください。

なお、meta_keyやmeta_queryを使う並び替えでは、そのキーが未保存の投稿は通常の結果から外れます。「日付未入力を最後に回したい」場合は、未入力を含める条件と並び順を別途設計してください。

3. 同じ日時の投稿が多く、順番が安定して見えない

複数の記事が同じ投稿日時、または同じカスタムフィールド値を持っている場合、その中の順番が期待と違って見えることがあります。日付だけでは順番を一意に決められないためです。

この場合は、日付に加えて ID などの二次ソートを使うと、確認しやすくなります。たとえば投稿日が同じものはIDの大きい順にしたい、というように補助的な並び順を足します。

最初の date-order-check.php の $args 全体を次へ置き換えます。後ろの表示ループとリセットはそのまま使います。

引数や処理の一部分だけを示した例です。このまま単独で貼らず、テンプレート内のWP_Queryとループへ組み込んでください。

PHPdate-order-with-id.php同じ投稿日がある時に、日付順に加えてID順も指定する$args差分
$args = [   'post_type'      => 'post',   'post_status'    => 'publish',   'posts_per_page' => 3,   'ignore_sticky_posts' => true,   'orderby'        => [      'date' => 'DESC',      'ID'   => 'DESC',   ],];

このコードのポイントは、orderbyを配列で指定している点です。まず投稿日で新しい順に並べ、同じ投稿日の中ではIDが大きいものを先にします。これで「同じ日付の中だけ順番が毎回違うように見える」状態を減らせます。

並べる日付と向きが決まったら、WP Query Builderで取得条件を整理できます。生成した$argsを表示ループへ渡す場合も、今日の日付の取得や同日時のID順は要件に合わせて確認してください。

日付の取得条件を組み立てる

投稿タイプ・日付条件・並び順から$argsを作れます。保存値の確認と、日付付きの表示ループはWordPress側で行います。

4. pre_get_posts や別の処理で上書きされている

テンプレートに書いた $args が正しくても、メインクエリを pre_get_posts で変更していたり、プラグインやテーマ側が並び順を変えていたりすると、意図した順番にならないことがあります。

特にアーカイブページや検索結果ページでは、テンプレート内のサブクエリと、WordPressが最初から持っているメインクエリを混同しやすいです。どちらのクエリを直しているのかを分けて確認してください。サブクエリを使うなら new WP_Query() の結果を表示しているか、メインクエリを変えるなら pre_get_posts の条件分岐が適切かを見る必要があります。

5. 別ループの投稿データが残っている

複数のWP_Queryを使っている場合、ループ後に wp_reset_postdata() を呼ばないと、その後のテンプレートタグが別ループの投稿を参照してしまうことがあります。これは並び順そのものを変える原因というより、「違う記事が表示されているように見える」原因です。

日付順の確認中に、タイトルや日付の表示が想定とズレる場合は、ループ後に wp_reset_postdata() があるかも確認してください。WordPress公式リファレンスの標準ループ例でも、別クエリのループ後に投稿データを戻す処理が示されています。

日付順に関わるWP_Queryの公式資料

WP_Queryの日付順は、orderby と order だけでなく、Date Parameters、Custom Field Parameters、ループ後の投稿データリセットとも関係します。この記事で扱った確認ポイントを公式資料で見る時は、次のページを開くと対応箇所を追いやすいです。

ACF Date Pickerを使っている場合は、WordPress側の資料だけでなく、ACF側の保存形式も確認してください。表示形式や返り値形式を変えても、WP_Queryが比較する保存値の考え方を押さえておくと、日付順のトラブルを減らせます。

公式リンク

公式ドキュメント

最後に確認したいこと

並べたい日付、向き、表示しているループ、保存値を分けます。投稿日順だけ合うのか、過去日だけ混じるのか、同日の中だけ不安定なのかを確認すれば、orderby、meta_key、保存形式のどこを直すか判断できます。

日付順の最終判断

  • 並び替える日付が投稿日・更新日・ACFのどれか決まっている
  • 同日データの二次ソートまで要件に含めた
  • ACF日付では保存値の形式とorderby方式を揃えた
  • 別処理の上書き有無を最小例との差で判断した
  • 変更前後の投稿ID順を比較した
WP Query BuilderBuilderで条件を組み直す条件を選び、WP_Queryのコードを画面で作れます。Builderでクエリを作る

この記事を書いた人

Huddly

Web制作 / フロントエンドエンジニア

WordPressとフロントエンド実装で迷いやすい点を、公式情報と検証結果を分けながら、初学者にも追いやすい順序で整理しています。

この記事の検証情報

検証環境

WordPress
7.1.4
PHP
8.3.36
テーマ
wpq-media + DDEV
対象
カスタム投稿 / taxonomy / meta_query

更新履歴

  • 2026年9月12日 本文と補助情報を更新
  • 2026年9月7日 初回公開

この記事を活用する

あとで見返す・共有する

お気に入りに保存できます。役に立ったポイントは、いいねや共有で教えてください。

任意のご支援 役に立ったときだけ、活動を応援できます OFUSEはサイト・記事制作に使います。支援の有無で、読める内容や使える機能は変わりません。