5

私はたくさん検索してきましたが、解決策が見つからないようです。

特定の時間に電子メール アラートをスケジュールできる PHP Web ページがあります。アラートを送信する日時を選択します。これは UNIX 形式で MySQL テーブルに格納されます。15 分ごとに実行され、日付と時刻が過去の場合にメールを送信するジョブがあります。これは、米国の同僚のために拡張する必要があることを除いて、すべて完全に機能します。私はアイルランドに拠点を置いているので、米国中のさまざまなタイムゾーンを管理する必要があります。ユーザーが登録したら選択する必要があるタイムゾーンの選択リストを追加することを計画しています...少なくともそれが始まりです。タイムゾーンの管理は問題ありません。サーバー時間と異なる時間を差し引いて、日付時間をUNIX形式で保存するだけでよいと思うからです。DST は別の問題ですが、これを克服する方法について何かアイデアはありますか?

UTC を基準時間として使用することを読みましたが、その場合でも同じ問題が発生することはありませんか?

ありがとうございます!

4

1 に答える 1

3

時刻はすでに UNIX タイムスタンプ形式になっているため、必要なのはユーザーの時差 (オフセット) を計算することだけです。たとえば、アイルランドはUTC/UTC+1タイムゾーンにあります。したがって、james_tがコメントで述べたような計算を行うだけで済みます。アイルランドのユーザーにメールを受け取る必要がある場合は、 で送信する必要があり9:00pm UTC+1ます8:00pm UTC。では、アイデアとは何ですか?

ユーザーがタイムゾーンを選択できるようにします。つまり、UTC からのオフセットを選択できます。データベースのどこかに保管してください(ユーザーテーブルまたは他のテーブルは関係ありません)。

オフセットを秒単位で変換:

$delta_time = -1 * $offset * 3600

次に、トリガー時間を計算します。

$trigger_time = time() + $delta_time;

これで、ユーザーのタイムゾーン設定に応じて、メール送信者が適切なタイミングで起動できるようになりました。

例えば:

$offset = 1; // summer in Ireland
$server_time = time(); // at the moment 1350509127
$delta_time = -1 * $offset * 3600; // -3600
$trigger_time = $server_time + $delta_time; // 1350505527

必要なのは$trigger_time、データベースの UNIX タイムスタンプと比較して、電子メールを送信するかどうかを決定することだけです。

多くの場合、純粋な +/- オフセットの代わりにPHP タイムゾーンを使用し、特定の場所で DST の変更が適用されたときに最新の状態を維持することは悪い考えではありません。

いくつかのテストを行います。これはそれほど難しくありません。

これは単なる一般的なアイデアであり、完全な実用的なソリューションではありません。

アップデート:

任意の 2 つのタイムゾーン間の時差を秒単位で計算するには、次のようなものを使用できます。

関数 delta_offset()

  function delta_offset($server_timezone, $user_timezone) {
    $dt = new DateTime('now', new DateTimeZone($server_timezone));
    $offset_server = $dt->getOffset();
    $dt->setTimezone(new DateTimeZone($user_timezone));
    $offset_user = $dt->getOffset();
    return $offset_user - $offset_server;
    }

オフセットを秒単位で取得するには:

  $server_tz = "Europe/London";
  $user_tz = "America/New_York";
  $offset = delta_offset($server_tz, $user_tz);  // offset in sec.

出力を作成します。

  $dt = new DateTime('now', new DateTimeZone('UTC'));
  echo "<pre>UTC date/time: " . $dt->format('l, F jS, <b>H:i:s</b>') . "\n";
  $dt = new DateTime('now', new DateTimeZone($server_tz));
  echo "London date/time: " . $dt->format('l, F jS, <b>H:i:s</b>') . "\n";
  $dt = new DateTime('now', new DateTimeZone($user_tz));
  echo "New York date/time: " . $dt->format('l, F jS, <b>H:i:s</b>') . "\n\n";
  echo "Time difference between London (UK) and New York (USA) is: <b>$offset_h</b> ($offset s)</pre>";  

ブラウザーでの出力 (この記事を書いている時点):

UTC date/time: Wednesday, October 17th, 22:32:27
London date/time: Wednesday, October 17th, 23:32:27
New York date/time: Wednesday, October 17th, 18:32:27

Time difference between London (UK) and New York (USA) is: -5:00 (-18000 s)

この場合、オフセットは -5 時間 (-18000 秒) ですが、関数の引数として指定されたタイムゾーンの DST 規則が変更されると、自動的に変更されます。

Delta-offsetは、異なるタイムゾーンのユーザーに電子メールを送信する必要がある時間の前後の情報を提供します。必要な+/- delta-offsetのは、電子メール送信者のスケジューラを使って簡単に行うことだけです。

これが問題の適切な解決策を得るのに役立つことを願っています.

更新 #2 - 例 (理論)

この状況を想像してみてください。

あなたの現在のサーバー時間はX7:00pm、現時点ではアイルランドです。私はセルビアに住んでいて、同じ DST ルールを持っていますが、1 時間後 (UTC+1/UTC+2) です。あなたと私の時間の差は+3600 seconds(1時間)です。

今、あなたは私に電子メールを送信する必要があります10:00pm(それは です9:00pm in Ireland)。

  • 現在時刻はXです。
  • デルタ オフセットは-1 * +3600 = -3600(デルタ オフセットに -1 を掛けた値) です。
  • あなたの場所での午後10時の送信時刻はX + 10800(3時間後)です。
  • 私の場所での午後10時の送信時間はX + 10800 + delta-offset = X + 7200(2時間後)です。

実際の時間がトリガー時間 (送信時間) 以上かどうかを確認する式は次のとおりです。

current_timestamp >= trigger_timestamp + delta_offset

数式で使用するには、関数からのデルタ オフセットをdelta_offset()乗算する必要があります。-1

これで、必要なときに電子メールを送信でき、ユーザーの現地時間を使用して送信されることを確認できます (ユーザーのタイムゾーン設定が正しい場合)。

注:この例 (セルビア - アイルランド = +1 時間) との違いは、DST の変更中は異なります。つまり、毎年 1 時間は同じタイムゾーン ( 0 delta-offset) にあり、1 時間は+2 hours delta-offset. これが可能なのは、セルビアでは DST の変更が 1 時間早く適用されるためです。そのため、時間が +1 変更されると、同じ変更がアイルランド時間に適用されるまで 60 分待たなければなりません *その後、+2 になります)。時計を通常時間 (0 差) にします。

于 2012-10-17T21:36:58.363 に答える