20

PHP のタイムゾーンに関するいくつかの問題は、しばらく頭の片隅にあり、現在行っていることよりも適切な処理方法があるかどうか疑問に思っていました。

すべての問題は、データベースに保存された日付の再フォーマットに関係しています。

複数のタイムゾーン (ユーザー用) をサポートする必要があるサイトを扱う場合、保存されたタイムスタンプのタイムゾーン オフフェストを正規化するために、CURRENT_TIMESTAMP属性またはNOW()関数を使用して常にサーバーのタイムゾーンと共に保存します。

この方法では、タイムスタンプが入力されたときに PHP に設定されたタイムゾーンを考慮する必要がありません (PHP の時間関数はタイムゾーンに対応しているため)。ユーザーごとに、彼の好みに応じて、次を使用してブートストラップファイルのどこかにタイムゾーンを設定しました。

date_default_timezone_set($timezone);

phpdate()関数を使用して日付をフォーマットしようとしている場合、MySQL は現在タイムスタンプを format で保存しているため、何らかの形式の変換を行う必要がありますY-m-d H:i:s。タイムゾーンに関係なく、次のように実行できます。

$date = date($format,strtotime($dbTimestamp));

これに関する問題は、date()strtotime()が両方ともタイムゾーンを認識する関数であることです。つまり、PHP のタイムゾーンがサーバーのタイムゾーンとは異なるように設定されている場合、タイムゾーン オフセットが 2 回適用されます (希望する 1 回ではなく)。

これに対処するために、私は通常、UNIX_TIMESTAMP()タイムゾーンを認識しない関数を使用して MySQL タイムスタンプを取得し、date()直接適用できるようにします。これにより、タイムゾーン オフセットを 1 回だけ適用します。

通常のようにこれらの列を取得できなくなったり、*すべての列をフェッチするために使用したりできないため、この「ハック」はあまり好きではありません (クエリが大幅に簡素化される場合があります)。また、使用するオプションではない場合もありますUNIX_TIMESTAMP()(特に、クエリ構成の抽象化があまりないオープンソース パッケージで使用する場合)。

別の問題は、CURRENT_TIMESTAMPまたはの使用がNOW()オプションではない場合にタイムスタンプを保存するときです-PHPで生成されたタイムスタンプを保存すると、回避したいタイムゾーンオフセットで保存されます。

私はおそらくここで本当に基本的な何かを見逃していますが、これまでのところ、これらの問題を処理するための一般的な解決策を考え出すことができなかったので、ケースバイケースで扱うことを余儀なくされています. あなたの考えは大歓迎です

4

4 に答える 4

12

数か月前、私たちはこれについてしばらく考えました。最終的に得られた手法は非常に単純です。

  1. 日付を GMT/UTC で保存します (例: 0 タイムゾーン オフセット)。
  2. データベースから取得した後に、現在のユーザーのタイムゾーン オフセットを適用します (たとえば、ユーザーに表示する前、またはいつでも)。

Unix タイムスタンプ形式を使用します。しかし、それは問題ではありません。

于 2008-12-08T16:12:08.073 に答える
7

PHP 5.2 以降では、タイムゾーンの操作を簡単にする DateTime を使用できます。

$datetime = new DateTime($dbTimestamp, $timezone);
echo $datetime->format('Y-m-d H:i:s');
$datetime->setTimezone(new DateTimeZone('Pacific/Nauru'));
echo $datetime->format('Y-m-d H:i:s');
于 2013-01-30T02:22:28.357 に答える
1

を使用して、MySQL がどこでも UTC を使用するように強制することができますSET time_zone

残念ながら、strtotime/UNIX_TIMESTAMP に関する回答は得られていません。実際、Postgres でも​​同じ問題を抱えています。

于 2008-12-06T21:23:39.023 に答える
0

オンラインで洗練されたソリューションが見つからなかったため、タイムゾーン HTML 選択ジェネレータースクリプトを作成しました。ここに出力が直接表示されます。それは次のようなものです:

<select name="timezone" id="timezone">
    <optgroup label="UTC -11:00">
        <option value="Pacific/Midway">UTC -11:00 Midway</option>
        <option value="Pacific/Niue">UTC -11:00 Niue</option>
        <option value="Pacific/Pago_Pago">UTC -11:00 Pago_Pago</option>
    </optgroup>
    <optgroup label="UTC -10:00">
        <option value="America/Adak">UTC -10:00 Adak</option>
        <option value="Pacific/Honolulu">UTC -10:00 Honolulu</option>
        <option value="Pacific/Johnston">UTC -10:00 Johnston</option>
        <option value="Pacific/Rarotonga">UTC -10:00 Rarotonga</option>
        <option value="Pacific/Tahiti">UTC -10:00 Tahiti</option>
    </optgroup>
    . . . . . . . . . . . . . .
    <optgroup label="UTC +13:00">
        <option value="Pacific/Apia">UTC +13:00 Apia</option>
        <option value="Pacific/Enderbury">UTC +13:00 Enderbury</option>
        <option value="Pacific/Fakaofo">UTC +13:00 Fakaofo</option>
        <option value="Pacific/Tongatapu">UTC +13:00 Tongatapu</option>
    </optgroup>
    <optgroup label="UTC +14:00">
        <option value="Pacific/Kiritimati">UTC +14:00 Kiritimati</option>
    </optgroup>
</select>

楽しみ!

于 2013-06-10T20:44:17.230 に答える