6

PHP / MySQL Webアプリケーションでタイムゾーンを使用するための最良の方法について数時間探していましたが、決定的な答えを見つけるのは困難です。私がこれまでに学んだことから、みんなのものをUTCでデータベースに保存するのが最善です(私が間違っている場合は訂正してください)。

ユーザーが登録するとき、私は彼らにそこのタイムゾーンを尋ね、それからそこのユーザーに対してそれを保存します。これは、ドロップダウンメニューとして次の形式になります。

<option value="Europe/London">(GMT) Greenwich Mean Time : London</option>

私が作成しているアプリを使用すると、ユーザーは将来、カレンダーのように人との取り決め(会議)を設定できます。明らかに、1年の間に、異なるタイムゾーンには異なる夏時間がありますが、これにどのように対応するかについてのアイデアはありますか?

英国のユーザーが2013年1月24日の午後3時に会議を設定し、カリフォルニアに住む人をこの会議に招待するとします。アメリカ人が自分のタイムゾーンでその会議を表示し、英国のユーザーが表示するようにするにはどうすればよいですか。彼/彼女のタイムゾーンでそれ?(両方のユーザーがサインアップし、タイムゾーンを設定していることに注意してください)。

誰かが明確な説明とおそらくこれのいくつかの例を持っていますか?または、それを見つけることができる場所を教えてもらえますか?

ありがとう

4

2 に答える 2

11

私はこの状況に、1年ちょっと前にプライベートジェットオペレーターのために書いたPHP/MySQLアプリケーションで広範囲に対処しました。これら2つのプラットフォームでタイムゾーンを処理するためのさまざまな戦略がありますが、私がそれをどのように行ったかを説明します。MySQLサーバーをUTCに設定し、ユーザープロファイルのサインアッププロセス中にユーザーが指定したタイムゾーンで各PHPスクリプトを実行します。

MySQLとPHP(PHP 5.2以降)はどちらもネイティブの日時データ型を持っています。MySQLのdatetimeはプリミティブデータ型ですが、PHP5.2以降では組み込みのDateTimeクラスが提供されています。MySQLの日時データ型にはタイムゾーンのメタデータは含まれていませんが、PHPのDateTimeオブジェクトには常にタイムゾーンが含まれています。PHP日時コンストラクターが2番目の引数でオプションのタイムゾーンを指定しない場合、PHP日時コンストラクターはphp環境変数を使用します。

MySQLとPHPの両方で、構成ファイルにデフォルトのタイムゾーンが設定されています。MySQLは、コマンドで接続が開始された後にユーザーが別のタイムゾーンを指定しない限り、各db接続の構成ファイルに設定された日時SET time_zone = [timezone];を使用します。PHPは、サーバー構成ファイルで設定されたタイムゾーンを使用して各スクリプトのタイムゾーン環境変数も設定します。この環境変数はdate_default_timezone_set()、スクリプトの開始後にPHP関数を使用してオーバーライドできます。

PHP DateTimeクラスには、 PHPDateTimeZoneオブジェクトであるtimezoneというプロパティがあります。DateTimeZoneオブジェクトは、正確なタイムゾーンの文字列を使用して指定されます。タイムゾーンのリストは包括的であり、世界中に数百の個別のタイムゾーンがあります。 PHPのタイムゾーンは、夏時間を自動的に考慮します。

ユーザーがWebアプリで日時を生成するときに、ユーザーのプロファイルのタイムゾーンでPHP日時オブジェクトを作成します。次に、このsetTimezoneメソッドを使用して、DateTimeオブジェクトをUTCタイムゾーンに変更します。これで、UTCでのユーザーの日時がわかり、値をデータベースに保存できます。DateTimeformatメソッドを使用して、MySQLで受け入れられる形式の文字列としてデータを表現します。

したがって、ユーザーは日時を生成し、ユーザーが指定したタイムゾーンでPHP日時オブジェクトを作成します。

// set using an include file for user profile
$user_timezone = new DateTimeZone('America/New_York'); 

// 1st arg in format accepted by PHP strtotime
$date_object1 = new DateTime('8/9/2012 5:19 PM', $user_timezone); 
$date_object1->setTimezone(new DateTimeZone('UTC'));
$formated_string = $date_object1->format('Y-m-d H:i:s');
$query_string = "INSERT INTO `t_table1` (`datetime1`) VALUES('$formated_string')";

データベースから値を取得するときは、UTCで作成してから、ユーザーのタイムゾーンに変換します。

$query_string = "SELECT `datetime1` FROM `t_table1`";
$date_object1 = new DateTime($datetime_string_from_mysql, new DateTimeZone('UTC'));
$date_object1->setTimezone($user_timezone);
$string_for_display_in_application = $date_object1->format('m/d/Y g:i a');

この方法を使用すると、日時の値は常にデータベース内のUTCに保存され、ユーザーは常に自分のプロファイルのタイムゾーンの値を経験します。PHPは、必要に応じて各タイムゾーンの夏時間を修正します。

1つの落とし穴:この説明は、MySQLタイムスタンプデータ型をカバーしていません。タイムスタンプデータ型ではなく、MySQL日時日付型を使用して日時値を格納することをお勧めします。タイムスタンプのデータ型については、こちらのマニュアルで説明されています。

編集: DateTimeZoneクラスの静的メソッドであるlistIdentifiers を使用して、すべてのPHPタイムゾーン文字列を含む配列を作成できます。

于 2012-08-09T13:22:09.493 に答える
4

MySQLでは、次のことを行う必要があります。

  1. 各ユーザーが選択したタイムゾーンを、そのユーザーに代わってデータベースクエリを実行するときに取得できる場所に保存します。文字列として保存できます。
  2. 特定のユーザーに代わって作業を行う直前(たとえば、予定の時間と日付を保存または取得する)SET time_zone = (stored time zone setting)

これにより、タイムゾーンが各人の現地時間に適切に変換されます。

編集:

これが機能するのは

  1. MySQLは、UTC(協定世界時、以前はグリニッジ標準時と呼ばれていました)を使用して、DATETIMEおよびTIMESTAMPデータ項目をテーブルに格納しようとします。
  2. これを正しく行うことができるのは、アプリケーションによって提供された各データ項目の正しいローカルタイムゾーンを知っている場合のみです。
  3. 異なるタイムゾーンを気にしないアプリケーションでは、MySQLサーバー全体の方法でこれを行います。https://dev.mysql.com/doc/refman/5.5/en/time-zone-support.htmlを参照してください。多国籍およびマルチタイムゾーンのアプリケーションを実行するほとんどの人は、サーバーのタイムゾーンを現地時間ではなくUTCに設定します。これにより、物事を整理しやすくなります
  4. 現地時間は1年のさまざまな時期にオンとオフが切り替わるため、日付とタイムゾーンもわからない限り、UTCから現地時間に時刻を変換しようとしてもほとんど意味がありません。イスラエル、アリゾナ、ニューヨークの3つすべてでこれを正しく行うようにしてください、あえて!イスラエルは過越の祭りとロシュハシャナで日中と標準時を切り替えます。アリゾナは切り替わりません、そしてニューヨークは米国連邦議会の気まぐれで切り替わります。
  5. セッションスコープのtime_zone設定(SET time_zone = something)があります。設定しない場合は、上記の項目3のタイムゾーン表現が使用されます。これを設定すると、サーバーはこれをタイムゾーンとして使用して、内部表現をクエリで送り返す表現に変換します。
  6. を発行すると、MySQLサーバーで使用可能なタイムゾーンの名前のリストを取得できますSELECT Name from mysql.time_zone_name。これにより、ユーザーがタイムゾーンを選択できるプルダウンメニューが表示されます。このクエリがアイテムを返さない場合は、https://dev.mysql.com/doc/refman/5.5/en/time-zone-support.htmlの下部をご覧ください。

つまり、セッションのtime_zone設定を特定のユーザーのタイムゾーンに設定してから、そのユーザーのタイムゾーンにいつでも戻ることができます。また、テーブルに配置されるときに、そのユーザーのタイムゾーンからMySQLの内部表現に変換されるDATETIMEまたはTIMESTAMPアイテム。INSERTUPDATE

注意:永続的なMySQL接続を持つWebアプリケーションでは、新しいユーザー要求の作業は接続のtime_zone設定を継承します。新しいユーザーのためにリセットすることを忘れないでください。

複数のユーザーの現地時間データを返すクエリを実行していて、それらのユーザーがたまたま異なるタイムゾーンにいる場合、このMySQLセッションごとの機能セットを利用することはできません。これを回避するには、ユーザーごとに異なるクエリを実行し、ユーザー間でtime_zone設定を変更します。

または、MySQL関数を使用できます

CONVERT_TZ(datetime,'UTC','user_time_zone')

または各アイテムに類似。

あるいは、JavaとDotNETには、独自の高品質のタイムゾーン操作システムがあります。したがって、UTCのtime_zone設定でMySQLサーバーを実行することを選択し、アプリケーションですべてのタイムゾーン変換を行うことができます。

于 2012-08-08T21:35:13.107 に答える