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/