2013-10-26 13 views
8

私のアプリケーションでは、GMT(深夜0時)までに残った時間を計算しようとしています。私はこれをやっている現時点では:不正なタイムゾーンを使用しているDateTime

$now = new DateTime(); 
$timeToMidnight = $now->setTimezone(new DateTimeZone('Europe/London'))->diff(new DateTime('tomorrow'))->format('%h hours, %i minutes and %s seconds'); 

コードが動作している、しかし、(GMTを使用して-1)の背後にある1時間のようです。現時点では時間は11時49分PMで、出力はこれです:

1 hours, 10 minutes and 36 seconds 

私は二重の私のphp.iniをチェックしましたし、私はまた、GMTとして設定タイムゾーンいることがあります。

date.timezone = Europe/London 

これも確認されていますphpinfo()をチェックしてください。

何がありますか?アプリケーションが正しいタイムゾーンを使用していないのはなぜですか?

+0

時計今夜 –

+0

@MarkBaker 、クロックは、転送ではなく、むしろ逆行しないでください?そして私はそれが2時まで起こらないことをかなり確信しています。 –

+0

今はロンドンの時間が真夜中の2時であることを意味します。イギリス夏時間... GMTは午後11時から2分ですのでGMT(UST)の真夜中までは58分です –

答えて

20

LinuxのPHP 5.5.5で、Europe/Londonphp.iniに設定してテストしました。私は実際にこれを行うために時計を4時間戻しました。私が再生するための最小限のコードは以下のとおりであった:

$d = new DateTime('tomorrow'); 
echo $d->format('c e'); 

(正しい)出力した:私は、タイムゾーンデータでPHPのバグやバグを探すつもりです

2013-10-27T00:00:00+01:00 Europe/London 

。これを知るには、今夜ロンドンのある夜中に他のプログラムが何をしているのかを見てみましょう。 Epoch Converterが、これはそのタイムスタンプを再確認するために1382828400.のUnixタイムスタンプを持つ必要があります私に語った、私はPHPで実行されていました:

$d = new DateTime('27-10-2013'); 
echo $d->format('U'); 

また

...のは、表示するようになっているものを見てみましょう、そう1382828400.を返さ
TZ=Europe/London date --date="@1382828400" +%c 

出力されました:正しい

Sun 27 Oct 2013 12:00:00 AM BST 

!だからtzdataは問題ありません。 PHPを見てみましょう。

私はdateコマンドと一緒に、あなたのサンプルコードを実行し、次の出力を得た:

1 hours, 29 minutes and 53 seconds 
Sat Oct 26 21:30:07 UTC 2013 
Sat Oct 26 22:30:07 BST 2013 

これは、もちろん、正しいです。

私はこの時点でtzdataとPHPの両方のバグを排除しており、構成上の問題とプログラマの期待を調べる必要があると思います。


まず、私が以前に述べたように、ヨーロッパ/ロンドンは夏の時間の概念がないため、年2回変化しない、UTCではありません。このような問題は発生しないため、ユーザーのタイムゾーンに関係なく、UTCでサーバーを実行することがベストプラクティスです。また、プログラムがUTCを内部的に使用してからローカルタイムゾーンに変換するベストプラクティスもあります。表示とユーザー入力のみ。

あなたのサーバの実行中のPHPは、実際には、デフォルトのタイムゾーンとしてEurope/LondonではなくUTCを使用するように設定されています。これは私があなたの問題を再現できる唯一の構成です。そのテストの結果は以下の通りであった。

date.timezone = UTC 

2 hours, 24 minutes and 36 seconds 
Sat Oct 26 21:35:24 UTC 2013 
Sat Oct 26 22:35:24 BST 2013 

は今後、あなたがそれを表示するにはUTCでの作業(とUnixのタイムスタンプで)どこ実用的、そして早くも処理ユーザの入力にローカル時間に変換し、遅けれ必要があり、することができますように。このような夏時間が終わることになるこのようなエッジケースは例外かもしれませんが、作成する新しいDateTimeオブジェクトの作成時に正しいタイムゾーンが設定されていることを確認するためには細心の注意が必要です。このような問題があることを認識しています。

も参照してください巨大かつ有益Daylight saving time and time zone best practices


最後に、これをやらせる、あなたのコードを "修正" する:GMTへBSTから英国の変化

$tz = new DateTimeZone('Europe/London'); 
$now = new DateTime('now', $tz); 
$midnight = new DateTime('tomorrow', $tz); 
$timeToMidnight = $now->diff($midnight); 
echo $timeToMidnight->format('%h hours, %i minutes and %s seconds'); 
+1

$ tz = new DateTimeZone( 'Europe/London')の+1。 –

関連する問題