12

私はこれについて少し説明を求めています。PHP 5.4 では、TZ 環境変数と、これまで行われていた「推測」がなくなりましたdate_default_timezone_get。そのため、サーバーのタイムゾーンを取得する方法がまったくないように思えます。

私の質問はこれです:PHP 5.4でサーバーのタイムゾーンを取得することは可能ですか? 手動で php.ini に設定できることは知っていますが、時刻を完全に把握できるコンピュータがある場合、それはばかげているように思えます。答えは「いいえ」だと思うので、プログラミング言語がタイムゾーンを特定できない理由を誰かが明らかにできるかもしれません。

4

6 に答える 6

4

すべてのシステムでタイムゾーンを推測する信頼できる方法はありません。異なるシステムは異なる規則を使用し、時には異なるタイムゾーン定義 (Unix や Windows など) を使用し、タイムゾーン指定子が競合することもあります (同じ 3 文字のゾーンの省略形が場所によって異なることを意味する場合があります)。したがって、システム間で移植可能なコードが必要な場合、それを確実に行う唯一の方法は、ユーザーに尋ねることです。たとえば、次のスレッドを参照してください: http://marc.info/?t=132356551500002&r=1&w=2 に関するいくつかの問題について (Derick Rethans からのメールを探してください - 彼は PHP 日時拡張機能のメンテナーです)。

信頼できるタイムゾーン (TZ 変数など) を見つける方法があれば、いつでも実行できますdate_default_timezone_set($_SERVER['TZ']);。ただし、一般的にこれは信頼できる方法ではないため、信頼するかどうかはユーザーが判断する必要があります。PHP では作成できません。

于 2012-07-31T21:09:02.200 に答える
2

ここを見ると、システムのタイムゾーンを推測しようとする PHP 5.3 のコードを見ることができます。それほど多くはありませんが、問題が表面化しているように見える場所であるため、推測を削除する理由は主に DST に関連しているようです.

推測プロセス全体の内訳は次のようになります。

  • すでにグローバルに定義されているかどうかを確認します (php.ini または以前の推測) (行 851-853)
  • 環境変数を確認してくださいTZ(私の経験ではほとんど定義されていません) (行 855-858)
  • php.ini から確認date.default_timezoneします (既に定義されているはずの特殊なケース) (860 ~ 872 行目)
  • と を比較して、システムからタイムゾーンを推測してみてtime()くださいlocaltime()。この呼び出しのスレッド化されたバージョンで問題が発生する可能性があるため、タイムゾーンの設定はオプションであると仕様に記載されているようです (行 873-890)。
  • Win32: WinAPI 関数GetTimeZoneInformation()を呼び出して、システムのタイム ゾーンを判別してみてください (893 ~ 928 行目)
  • Netware:_timezone定義されている場合は値を確認します (行 929-937)
  • 上記のチェックのいずれも成功しなかった場合は、UTC にフォールバックします

推測することしかできませんが、そもそも推測であり、常に信頼できるとは限らないため、削除しただけかもしれません。

また、PHP の人気により、顧客がサーバーと同じタイムゾーンにいないことが多い Linux ベースの共有ホスティング プランのほぼすべてにインストールされているため、それらの人々のためにサーバーのタイムゾーンにフォールバックすることは、デフォルトで UTC を使用することに勝るものはありません。そうすると、これらの顧客が SO に来て PHP の時間が間違っている理由を尋ねなければならないので、混乱を招くだけです。

私はCと標準に十分に精通していませんがlocaltime、マルチスレッドコードに問題があるか、場合によっては利用できないことに基づいてタイムゾーンを推測しているようです。Windows 以外のプラットフォームでは、これがタイムゾーンを決定するための最良の方法であるため、マルチスレッド PHP で何も返さないか、問題を引き起こす可能性が半分あるとしたら、意味がありません。

もちろん、タイムゾーンとオフセットが時期に基づいて異なるいくつかの場所では、DST の問題があります。

それが役立つことを願っています。

于 2012-07-31T21:26:02.303 に答える
0

いいえ、現時点では PC でタイムゾーンを取得する方法はありません。

于 2012-07-31T19:40:37.880 に答える
0

私は最近、プロジェクト用にいくつかのサーバーをゼロから構築しました。サーバーがローカルタイムゾーンを使用していた他のプロジェクトでの以前の経験により、すべてのサーバーに「UTC」タイムゾーンを使用させることにしました。これにより、ログ ファイルが 7 時間 (UTC - PST) ずれることになりましたが、(以前のプロジェクトから) ローカル タイムゾーンの設定によって引き起こされた不整合は解消されました。

強制一貫性は、OS 層とアプリ層で役立つことが証明されました。OS レイヤーでは、物理的な場所に関係なく、すべてのログ ファイル エントリを中央の場所から (udp 経由の syslog 経由で) 表示できます。また、アプリケーション レイヤーでは、すべてのタイムスタンプを UTC として保存し、タイムゾーンを指定したユーザーのレンダリングで変換する方がはるかに簡単でした。この一方向の変換は、保存時にタイムスタンプをサーバーのローカル タイムゾーンから UTC に変換し、レンダリング時にユーザーが選択したタイムゾーンに変換する必要がある双方向の変換よりもはるかに簡単です。

したがって、サーバーがタイムゾーンを認識しなければならない非常にやむを得ない理由がない限り、私は 5.4 より前のデフォルトであった UTC に固執することを選択します。 "

于 2012-07-31T20:49:02.997 に答える
0

これはただの勝手な推測です。次の方法でタイムゾーンを取得できますか。

date('H', 0);またはそのようなもの?つまり、unixtime スタンプはすべての地域で同じですが、Hour異なるため、どのタイムゾーンが使用されているかを時間に基づいて知ることができるはずではありませんか?

于 2012-07-31T21:17:24.133 に答える
0

Windows サーバーでは、ちょっとした計算でローカル システムのタイム ゾーンを取得できます。

<?php
  date_default_timezone_set('UTC');

  $nowUTC = new DateTime();
  $nowSys = new DateTime(exec('echo %time%'));
  $offset = $nowUTC->diff($nowSys);

  echo $nowUTC->format('H:i:s') . '<br />';
  echo $nowSys->format('H:i:s') . '<br />';
  echo $offset->format('%H');
?>

このコードの出力を書いている時点での私のロケール (UTC-05) からは次のようになります。

22:16:41
17:16:41
05

注意点が 1 つあります。タイムスタンプが 1 秒ずれて、$offset変数が 4:59:59 になることがあります。一貫して正しいタイムゾーンを取得すると、安全のために丸めが少し行われます。

于 2013-01-14T22:17:46.613 に答える