主な問題は、MySQL のタイムゾーンのサポートがばかげていることです。他のほとんどのデータベースではタイムゾーンを datetime 列の一部として定義できますが、MySQL では定義できません。代わりに、接続全体またはサーバー全体のタイムゾーン設定を行う必要があります。
最善の策は、MySQL がすべての日時を GMT / UTC として保存するようにすることです。SET time_zone = 'UTC'
これは、接続時に実行することで強制できます。文字セットの設定と同時に行います。接続文字セットを設定していますよね?
PHP 側では、 DateTimeとDateTimeZoneの組み合わせを使用して、MySQL から日時を取得し、ユーザーのタイムゾーンで表示できます。たとえば2012-11-13 14:15:16
、MySQLDATETIME
列から日付を取得するとします。PHP 対話型プロンプトから:
php > $from_mysql = '2012-11-13 14:15:16';
php > $utc = new DateTimeZone('UTC');
php > $ts = new DateTime($from_mysql, $utc);
php > $pdt = new DateTimeZone('America/Los_Angeles');
php > $ts_pdt = clone $ts;
php > $ts_pdt->setTimezone($pdt);
php > echo $ts_pdt->format('r'), "\n";
Tue, 13 Nov 2012 06:15:16 -0800
示されているように、UTC が を使用して設定したタイムゾーンでない場合は、UTC であることを明示的に伝えて DateTime を作成するだけですdate_default_timezone_set
。DateTime のタイムゾーンを切り替えるのは、新しいものを与えるのと同じくらい簡単です。ここを使っclone
てコピーを作成しました。DateTimes は変更可能であり、誤って上書きしてしまうことがあります。
逆日付計算も同じように機能します。選択内容を UTC に変換し、ネイティブの数値で計算を実行するだけです。
tl;dr:
- 日時の計算をUTC (GMT) のみで保存および実行する
- ユーザーのタイムゾーンのみですべての日時を表示する