こんにちわ、PHPエンジニアのエンジニア婦人(@naho_osada)です。
PHPエンジニアとして9年~の経験があります。
サイト制作者の皆様、エンジニアの皆様は「何らかの情報を取得して、日時をと記事タイトルを表示させる」…なんてことは、割とやると思います。日常茶飯事で。
そこで、時間を表示させるときに、まさかの時間がずれてしまうバグに遭遇しました…
※本件はWordpress内でdate関数を実行するときに起こり得るものです。
元の日付は正しいのに、表示すると昨日の日付!?
PHPで日付と言えばdate関数、strtotime関数です。
例えば
「Tue, 30 Apr 2019 07:39:56 +0900」
のような日付があるけれど、「〇月〇日で表示したい」とき。
通常、PHPではstrtotimeで時間をUNIXタイムに戻し、そこからdate関数で解読できる日付を表示していることが多いと思います。
これをstrtotimeを通してdateで出力すると、前日になってしまいます。
しかし前日表示になっていない場合もあります。例えば、
「Sun, 13 Jan 2019 13:55:46 +0900」
これは当日の表示になります。
-9時間、時差補正がない
時間まで出力してみるとわかるのですが、+9時間が抜け落ちた変換になっています。
標準時間になっているのですね。
そのため、strotimeするときに+9時間を指定してあげる必要があります。
strtotime('Tue, 30 Apr 2019 07:39:56 +0900' + 9 hours);
このあとdate関数をかけると、日本時間で正しく表示されます。
何故時差補正がされないのか?追及
これで解決はしました…が、ちょっと待って。
確かに+9時間すれば、目的は達成されます。でもどうしてそうなった?
調べたところ、私のサーバーではタイムゾーンがちゃんとAsia/Tokyoに設定されています。いやまあ基本なんだけど、こういう時は確認しましょう。
更に念のため、ベタなPHPプログラムを書いて実行してみたところ、正しく日時が表示されました。
$a = 'Tue, 30 Apr 2019 07:39:56 +0900';
echo $a . 'を変換 : ' . date('Y-m-d H:i:s', strtotime($a));
そうとなると…原因は、WordPressなのか?事件はWordpressの中で起きている?
原因は「WordPressのデフォルトタイムゾーンの設定」
ちょっと調べてみたら、出てきました。WordPressの時刻はデフォルトで「UTC」なんですね。
wp-setting.phpにありました。
このために、Wordpressを通したdate関数を使うと、日付がずれてしまう。
しかし、Wordpressに投稿した日時を表示する(データベースに登録されている日時を変換する)場合は大丈夫でした。これはWordpressの設定からできる、タイムゾーンが「東京」に設定されているためでしょう。
ではなぜ問題が?というところですが、上記の問題が発生したのは、外部のRSSを取得して日時表示をした場合、Wordpress管理外のものを扱ったときに発生しました。
そうとわかれば、タイムゾーンを上記の方法でもいいけれど、タイムゾーンを適切にAsia/Tokyoにしてあげればよりスマートではないか。
テーマ内の共通部分で再設定
WordPressの画面を表示するときに必ず読み込むファイルにタイムゾーンを設定する関数を書いておいたら良い。そうするとプログラム中に+9 hoursを書く必要はなくなります。問題は、どこに書くか。
私の出した最適解は、テーマ内function.phpに書き込むことです。
date_default_timezone_set( 'Asia/Tokyo' );
こうしておくと、常にタイムゾーンはAsia/Tokyoを向いてくれるので+9時間を気にしなくてよくなります。
他のWordPressの投稿記事は既にAsia/Tokyoで判断されているだけなので、二重に設定されるだけで特に問題は起きません。
wp-setting.phpのタイムゾーンを変えるのも方法としては悪くないですが、それやるとWordPressの更新で一発アウトです。
コアファイルに書き込むのは避けてください。
まとめ
- WordPress内で、外部の情報を取得したときに時間がずれた場合、WordPress内タイムゾーンを疑う。
- テーマ内functions.phpにタイムゾーンを設定すれば、解決する。
但し日本時間の-9時間なので、日付のみ表示している場合は運よく問題がなく、気づかないこともあるかもしれません。