異なるタイムゾーンの PHP サーバーと MySQL サーバーの処理
質問
GoDaddy や Network Solutions などの標準的な共有ホスティング パッケージを使用している人にとって、ホスティング サーバー (PHP) と MySQL サーバーのタイム ゾーンが異なる場合、日時の変換はどのように処理すればよいでしょうか?
また、サイトへの訪問者がどのタイムゾーンにいるかを判断し、日時変数を適切に操作するためのベストプラクティスのアドバイスを持っている人はいますか?
解決
PHP 5.1.0以降では使用できます date_default_timezone_set() スクリプト内のすべての日付/時刻関数で使用されるデフォルトのタイムゾーンを設定する関数。
MySQLの場合(引用元) MySQL サーバーのタイムゾーンのサポート ページ)
MySQL 4.1.3 より前では、サーバーは起動時に設定されたシステム タイム ゾーンでのみ動作します。MySQL 4.1.3 以降、サーバーはいくつかのタイムゾーン設定を維持し、その一部は実行時に変更できます。
興味深いのは、接続ごとのタイム ゾーンの設定です。これはスクリプトの先頭で使用します。
SET timezone = 'Europe/London';
クライアントのタイムゾーン設定の検出に関しては、JavaScript を少し使用してその情報を取得して Cookie に保存し、その後のページ読み取りでそれを使用して、適切なタイムゾーンを計算できます。
//Returns the offset (time difference) between Greenwich Mean Time (GMT)
//and local time of Date object, in minutes.
var offset = new Date().getTimezoneOffset();
document.cookie = 'timezoneOffset=' + escape(offset);
あるいは、ユーザーが自分でタイムゾーンを設定できるようにすることもできます。
他のヒント
Željko Živković からの回答を参照してください。「ヨーロッパ/ロンドン」のようなタイムゾーン記述子は、mySQL 管理者がシステムにタイムゾーン テーブルを追加し、それらを更新し続けている場合にのみ機能します。
それ以外の場合は、「-4:00」のような数値オフセットに制限されます。幸いなことに、php date('P') 形式がそれを提供します (5.1.3 以降)。
つまり、あなたが持っているかもしれないアプリ構成ファイル
define('TZ', 'US/Pacific');
....
if (defined('TZ') && function_exists('date_default_timezone_set')) {
date_default_timezone_set(TZ);
$mdb2->exec("SET SESSION time_zone = " . $mdb2->quote(date('P')));
}
これは、PHP と mySQL が使用するタイムゾーン オフセットについて合意することを意味します。
時刻値の保存には常に TIMESTAMP を使用してください. 。この列は実際には UNIX_TIME (エポック) として保存されますが、書き込み時に現在の time_zone オフセットから暗黙的に変換され、読み取り時に逆変換されます。
他のタイムゾーンのユーザーの時刻を表示したい場合は、グローバルのdefine()の代わりに、上記で指定したタイムゾーンを設定します。TIMESTAMP 値は、アプリが結果セットを確認するまでに mySQL によって自動的に変換されます (これは問題になる場合があります。イベントの元のタイムゾーンも実際に知りたい場合は、別の列に含める必要があります)。
「すべての時間を int として保存すればいいのではないか」という限り、日付を比較して検証する能力が失われます。 いつも アプリ レベルで日付表現に変換する必要があります (データを直接見ると目が疲れます。1254369600 で何が起こったでしょうか?)
以前に dateTime 型で問題があったため、私はすべての日付を bigint として保存します。time() PHP 関数の結果をそこに保存すると、同じタイムゾーンにあるものとしてカウントされるようになります:)
PHPでは、php.iniファイルでタイムゾーンを設定します。 ini_set("date.timezone", "America/Los_Angeles");
または、特定のページでは次のように実行できます。 date_default_timezone_set("America/Los_Angeles");
mysqlでは次のようにできます: SET GLOBAL time_zone = 'America/Los_Angeles';