5 と表示されている理由と、これが技術的に正しい理由
Sydneyでは、DST が 2013-10-06 02:00:00 に開始されるため、それにまたがる日付で 1 時間を失います。
strtime を呼び出すと、時間をシドニー時間として解釈しますが、Unix タイムスタンプを返します。タイムスタンプの 2 番目のセットを UTC に変換すると、2013-09-30 14:00:00 から 2013-10-06 13:00:00 までの範囲が得られますが、これは 6 日ではないため、 5に切り捨てます。
DST 移行を無視して時差を取得する方法
代わりにDateTimeオブジェクトを使用してみてください。
$tz=new DateTimeZone('Australia/Sydney');
$start=new DateTime('2013-10-01', $tz);
$end=new DateTime('2013-10-07', $tz);
$diff=$end->diff($start);
//displays 6
echo "difference in days is ".$diff->d."\n";
DateTime::diff の動作が異なるのはなぜですか?
「なぜそれが機能するのですか?」と尋ねるかもしれません。- 結局のところ、それらの時間の間に 6 日はありません。5 日と 23 時間です。
その理由は、DateTime::diffが実際に DST 移行を修正するためです。それを理解するためにソースを読まなければなりませんでした - 修正は内部のtimelib_diff関数の中で行われます。この修正は、次のすべてに該当する場合に行われます
- 各 DateTime は同じタイムゾーンを使用します
- タイムゾーンは地理的な ID である必要があり、GMT のような略語ではありません
- 各 DateTime には異なる DST オフセットが必要です (つまり、1 つは DST にあり、もう 1 つはそうでない)。
この点を説明するために、DST への切り替えの両側で数時間だけ 2 回使用するとどうなるかを次に示します。
$tz=new DateTimeZone('Australia/Sydney');
$start=new DateTime('2013-10-06 00:00:00', $tz);
$end=new DateTime('2013-10-06 04:00:00', $tz);
//diff will correct for the DST transition
$diffApparent=$end->diff($start);
//but timestamps represent the reality
$diffActual=($end->getTimestamp() - $start->getTimestamp()) / 3600;
echo "Apparent difference is {$diffApparent->h} hours\n";
echo "Actual difference is {$diffActual} hours\n";
これは出力します
Apparent difference is 4 hours
Actual difference is 3 hours