WordPressの日時は、『WordPressタイムスタンプ』という独自の考え方があります。
(WP5.3以降は段階的に廃止)。
これがやっかいで、いろいろなところで対応策が出ています。代表的なのは『date_i18n()を使う』です。
なにがやっかいなのか?そのへんの話です。
開発者向けの話です。テーマ・プラグインを作っている人は要チェック。
WPタイムスタンプという日時
WordPressの日時は独特です。WordPressタイムスタンプという独自のタイムスタンプを使います。
WPタイムスタンプ = Unixタイムスタンプ(≒ UTC) + タイムゾーンオフセット
UNIXタイム
POSIXタイム。
UTCの1970年1月1日午前0時0分0秒を基準に何秒進んだかで表現する時間。
イギリスのグリニッジ(経度0)の時間がベースで、時差(秒)をプラマイ(+,-)して対象地域の時間を計算する。
(タイムゾーン、ローカライズ)
UNIXタイムはタイムゾーンを入れない時間をいう。
(経度0のUNIXタイム)
多くのシステムで採用されているためUNIX OSの時間とはかぎらない。また、閏秒(うるう秒)が正確でない。
秒数で表現するため値に限界があり、2038年1月19日12時14分8秒になると計算が狂うという問題がある。(2038年問題)
UTC(協定世界時)
Coordinated Universal Time
イギリス・ロンドンのグリニッジを基準にしたグリニッジ標準時(GMT)から発展させた世界の標準時。
(グリニッジは経度の基準でもある。経度0。)
通信分野などUTCとGMTは同じものとして扱うこともある。
ロンドンと日本の時差は9時間で、日本標準時は『+0900 (JST)』と書く。
(日本はロンドンより9時間早い。)
タイムゾーンオフセットはUNIXタイムスタンプ(ロンドン・グリニッジの時間)からの時差。WordPressでは、管理画面で設定されたタイムゾーンを整数値に変換します。
日本の時差9時間の秒 = タイムゾーンオフセット値
9(時間) = 540(分) = 32400(秒)
一般的な日時と何がちがうのか?
WPタイムスタンプと一般的な日時には、あまりちがいはありません。日時は一般的に、
UNIXタイムスタンプ + タイムゾーンオフセット
だからです。ちがいはたったひとつです。
タイムゾーンオフセットをどこから取ってるくるか?
普通のタイムスタンプは、OSのタイムゾーンやプログラムの設定の値からタイムゾーンオフセット値を計算します。
(たとえばPHPプログラムならphp.ini。)
NTP, SNTPで、時間を管理するサーバーと同期することもある。
OSの最初の設定で『地域』の設定をしますよね? これでパソコンやサーバーの時刻が日本時間になります。
WPタイムスタンプのタイムゾーンは管理画面の設定で、WordPressが稼働しているサーバーのOS設定や、php.iniのタイムゾーンの設定は無視されます。
サーバーが日本時間でも、WordPressでアメリカに設定すればWordPress内の時間はアメリカ時間になります。
システム独自でタイムゾーンを設定・管理することはあります。WordPressの日時は決して特殊なものではありません。
なにが問題なのか?
このちがいは大きな問題というものではなく、ただ開発者や運用者が混乱することがありました。
WordPrressでは、最初にphp.iniのタイムゾーン設定を無効化するからです。
// WordPress calculates offsets from UTC.
date_default_timezone_set( 'UTC' );
タイムゾーンを時差なしにしてしまうんですね?
PHPの関数と結果がちがう
WordPressのカスタマイズで、PHPの関数を使って現在時刻を取得するとロンドン日時になります。
date()
new DateTime()
PHPの関数は、WordPressの設定のタイムゾーンなんて知らないし、php.iniはWordPressの初期処理でUTCにリセットされるから。
そこで、WordPressで用意されている関数を使います。
date_i18n()
date_i18n()はWordPress設定のタイムゾーンを使う。
date_default_timezone_set()で変えてはいけない!
WordPressのカスタマイズで、
date_default_timezone_set('Asia/Tokyo');
にすれば直りますが、WordPressではdate_default_timezone_set()で変更するのを推奨していません。
WordPressのシステム全体に影響するからです。
分かってやる分にはかまいません。ただし自己責任です。
もし使うなら、ほかに影響しないようにします。
// 既存のタイムゾーン取得
$tz = date_default_timezone_get();
// タイムゾーン変更
$tz_new = 'Asia/Tokyo';
date_default_timezone_set($tz_new);
// ここで作業する
// タイムゾーンを戻す
date_default_timezone_set($tz);
でもこれは、バックグラウンドで動作するプラグインなどに影響するかもしれません。
ここは、phpのDateTime, DateTimeImmutableクラスを使いましょう。プログラム全体のタイムゾーンを変えずに任意のタイムゾーンが使えます。
$date = new DateTime();
$tz = new DateTimeZone('Asia/Tokyo');
$date->setTimezone($tz);
echo $date->format('Y-m-d H:i:s');
日時データを2つ持っている
WordPressのデータベースには、WPタイムスタンプ(タイムゾーン込み)とUTC(タイムゾーン抜き)の時間が登録されています。
ID | ・・・ | post_date | post_date_gmt | ・・・ |
---|---|---|---|---|
13 | ・・・ | 2017/05/26 19:30:42 | 2017/05/26 10:30:42 | ・・・ |
comment_ID | ・・・ | comment_date | comment_date_gmt | ・・・ |
---|---|---|---|---|
47 | ・・・ | 2017/09/22 20:50:38 | 2017/09/22 11:50:38 | ・・・ |
WordPressの日時取得はGMT(UTC)時刻も取得できます。
// 現在日時取得
echo date_i18n('Y-m-d H:i:s') . PHP_EOL; // WPタイムスタンプ
echo date_i18n('Y-m-d H:i:s', false, true); . PHP_EOL; // GMT
// 投稿日時取得
$post = get_post( 13 );
echo $post->post_date . PHP_EOL;;
echo $post->post_date_gmt . PHP_EOL;
2020-01-03 13:11:56
2020-01-03 04:11:56
2017-05-26 19:30:42
2017-05-26 10:30:42
バージョン5.3以降はフェードアウト
WordPressの開発コミュニティーでも、PHPやシステム(OS)、他のシステムとの上位互換がないことに問題は感じていたようです。
WordPress5.3では、コア機能でのWPタイムスタンプの使用を段階的に廃止すると宣言しました。
それのための関数などのAPIも新しく提供されました。
かといって、今までと日時の扱い方が急に変わるわけではないので、必要がないかぎり急いで修正する必要はありません。
もちろん、これからカスタマイズするときは新しいAPIを使ったほうがいいです。いずれ修正することになるので。