0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

WordPress の中で date('Y-m-d') を呼ぶと、日本時間の朝9時までは前日の日付が返ります【php.ini を Asia/Tokyo にしていても】

0
Posted at

WordPress の中で PHP の date() を呼ぶと、UTC の日時が返ります。php.ini の date.timezone を Asia/Tokyo にしていても、WordPress の設定画面でタイムゾーンを「東京」にしていても、同じです。日本時間の0時から9時までは、date('Y-m-d') が前日の日付になります。WordPress 7.1.2 で、時計を日本時間の 2026-12-11 08:30 にずらして測りました。

呼び方 返ってきた値 日本時間として正しいか
date('Y-m-d H:i') 2026-12-10 23:30 前日
gmdate('Y-m-d H:i') 2026-12-10 23:30 UTC(仕様どおり)
(new DateTime())->format('Y-m-d H:i') 2026-12-10 23:30 前日
wp_date('Y-m-d H:i') 2026-12-11 08:30 正しい
current_time('Y-m-d H:i') 2026-12-11 08:30 正しい
current_datetime()->format('Y-m-d H:i') 2026-12-11 08:30 正しい

(php.ini は date.timezone=Asia/Tokyo、WordPress の設定は timezone_string=Asia/Tokyo)

同じ時刻に昼の12:00で測ると、date() も DateTime も日付は 2026-12-11 で、時刻だけが9時間ずれます。日付がずれるのは、日本時間の0時〜9時の9時間だけです。

先に断っておくと、これは WordPress の公式な振る舞いです。WordPress 5.3 の Date/Time の改善を説明した Make WordPress Core の記事に、「WordPress sets PHP time zone to UTC during boot」とあり、date_default_timezone_set() で変えてはいけない(「this one is hard requirement for correct core operation!」)と書かれています。同じ記事で、wp_date() と current_datetime() が紹介されています。ここで書くのは、それが日付の比較でどう効くかを、実際に時計をずらして測った結果です。

php.ini の設定は、WordPress が上書きする

同じスクリプトを、WordPress を読み込まずに動かした場合と、読み込んだ場合で比べました。

PHP単体   php.ini=Asia/Tokyo  実行時=Asia/Tokyo  date()=2026-12-11 08:30
WP内      php.ini=Asia/Tokyo  実行時=UTC          date()=2026-12-10 23:30

WordPress を読み込んだ瞬間に、実行時のタイムゾーンが UTC に変わっています。wp-settings.php の72〜73行目です。

// phpcs:ignore WordPress.DateTime.RestrictedFunctions.timezone_change_date_default_timezone_set
date_default_timezone_set( 'UTC' );

WP-CLI で動かしたスクリプトや、プラグインの単体テストで WordPress を読み込まずに試した関数は、php.ini のタイムゾーンで動きます。WordPress の中に入れると、同じ関数が UTC で動きます。手元で試したときは正しかったのに、という形で出てきます。

日付の比較が、9時間遅れる

自作の WordPress プラグイン Rapls AI Chatbot では、AI モデルの提供終了日が来たら後継のモデルに切り替える処理があります。今日がその日以降かを、こう判定しています。

function raplsaich_retirement_in_effect(string $date): bool {
    if ($date === '') {
        return true;
    }
    return wp_date('Y-m-d') >= $date;
}

ここを date() で書いていたら、どうなるか。終了日を 2026-12-11 として、日本時間の 12月11日 08:30 に判定しました。

date('Y-m-d') >= '2026-12-11'    → false
wp_date('Y-m-d') >= '2026-12-11' → true

date() では、まだ12月10日です。提供が終わったモデルに、朝9時までリクエストを送り続けることになります。

逆向きの場合もあります。「今日の0時以降に作られた投稿」のように日付で範囲を切る処理を date() で書くと、日本時間の0時〜9時に作られた投稿が前日の側に入ります。

current_time('timestamp') は、Unix タイムスタンプではない

もう1つ、同じ時刻に測った値です。

time()=1796945400  current_time('timestamp')=1796977800  差=32400秒

current_time('timestamp') は、time() より9時間(32400秒)先の数字を返します。上の Make WordPress Core の記事では、この値を「a sum of Unix timestamp with a time zone offset」と説明していて、Unix タイムスタンプと呼んでいたのは誤りだった、としています。

この値を date() に渡すと、日本時間の文字列が出てくるので、正しく見えます。ところが wp_date() に渡すと、wp_date() も9時間足すので、もう一度ずれます。

date('H:i', current_time('timestamp'))    = 08:30
wp_date('H:i', current_time('timestamp')) = 17:30
wp_date('H:i', time())                    = 08:30

Unix タイムスタンプが欲しいときは time()、日本時間の日時が欲しいときは current_datetime() か wp_date() を使います。

使い分け

  • 日本時間(サイトのタイムゾーン)の日付・時刻の文字列:wp_date()
  • サイトのタイムゾーンつきの DateTimeImmutable:current_datetime()
  • Unix タイムスタンプ:time()
  • UTC の文字列(ログや DB に保存するとき):gmdate()
  • date() と引数なしの new DateTime() は、WordPress の中では UTC だと思って読む

あなたのプラグインで、date('Y-m-d') で「今日」を判定している場所はありませんか。

手元で試すコマンド

WordPress の直下に置いて動かします。時計をずらすには libfaketime を使いました(Ubuntu なら apt install faketime)。

<?php
$_SERVER['HTTP_HOST'] = 'localhost';
$_SERVER['REQUEST_URI'] = '/';
require __DIR__ . '/wp-load.php';
update_option('timezone_string', 'Asia/Tokyo');

$rows = [
    "date('Y-m-d H:i')"             => date('Y-m-d H:i'),
    "gmdate('Y-m-d H:i')"           => gmdate('Y-m-d H:i'),
    "wp_date('Y-m-d H:i')"          => wp_date('Y-m-d H:i'),
    "current_time('Y-m-d H:i')"     => current_time('Y-m-d H:i'),
    "(new DateTime())->format()"    => (new DateTime())->format('Y-m-d H:i'),
    "current_datetime()->format()"  => current_datetime()->format('Y-m-d H:i'),
    "date_default_timezone_get()"   => date_default_timezone_get(),
];
foreach ($rows as $k => $v) {
    printf("%-32s %s\n", $k, $v);
}
TZ=Asia/Tokyo faketime "2026-12-11 08:30:00" php -d date.timezone=Asia/Tokyo tz.php

このスクリプトは、サイトのタイムゾーン設定を Asia/Tokyo に書き換えます。検証用の WordPress で動かしてください。

ふだんはraplsworks.comで、WordPressプラグイン開発やClaude Codeまわりのことを書いています。
https://raplsworks.com/

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?