これは完全な答えではありませんが、少なくともそれは何かです。
ここには、次の 2 つの問題が考えられます。
- ircmaxell が述べたように、PHP はタイムゾーン操作ビット内のどこかでうるう秒を消費している可能性がありますが、さらに調査が必要です。
- しかし個人的には、PHP が数秒の「オーバーフロー」を数分に「修正」していると期待しています。
DateTime
コンストラクターは、指定された引数を を処理するのと同じコードに渡します。このコードはstrtotime
、完全に偽の日付 (たとえば 2 月 31 日) を取得し、意味のあるものに変換することでよく知られています。
ドキュメントでのうるう秒への唯一の参照は次のstrptime
とおりです。
「tm_sec」にはうるう秒が含まれます (現在は年に 2 秒まで)。
たとえば、PHP の対話型プロンプトから省略されます。
php > $eviler_format = '%Y-%m-%d %H:%M:%S %z';
php > $evil = '2012-12-31 23:59:59 +0000';
php > var_dump(strptime($evil, $eviler_format));
array(9) {
'tm_sec' =>
int(59) // ...
}
php > $evil = '2012-12-31 23:59:60 +0000';
php > var_dump(strptime($evil, $eviler_format));
array(9) {
'tm_sec' =>
int(60) // ...
}
php > $evil = '2012-12-31 23:59:61 +0000';
php > var_dump(strptime($evil, $eviler_format));
array(9) {
'tm_sec' =>
int(61) // ...
}
php > $evil = '2012-12-31 23:59:62 +0000';
php > var_dump(strptime($evil, $eviler_format));
bool(false)
残念ながら、12 月 31 日ではない「うるう秒」も必要です。
php > $evil = '2012-01-07 23:59:61 +0000';
php > var_dump(strptime($evil, $eviler_format));
array(9) {
'tm_sec' =>
int(61)
'tm_min' =>
int(59)
'tm_hour' =>
int(23)
'tm_mday' =>
int(7)
'tm_mon' =>
int(0)
'tm_year' =>
int(112)
'tm_wday' =>
int(6)
'tm_yday' =>
int(6)
'unparsed' =>
string(0) ""
}
または真夜中ではない:
php > $evil = '2012-01-07 08:59:61 +0000';
php > var_dump(strptime($evil, $eviler_format));
array(9) {
'tm_sec' =>
int(61)
'tm_min' =>
int(59)
'tm_hour' =>
int(8)
'tm_mday' =>
int(7)
'tm_mon' =>
int(0)
'tm_year' =>
int(112)
'tm_wday' =>
int(6)
'tm_yday' =>
int(6)
'unparsed' =>
string(0) ""
}
さらに、それはまったく接続さDateTime
れていない完全にプレゼンテーション機能です。数学を行うことはできません。物事の明確な性質を考えると、実際のうるう秒を取得することは現実の世界では不可能です。ここは駄目です。
結論: PHP はうるう秒を考慮していません。サーバーが、それを気にする上流の NTP サーバーと同期されていることを確認してください。最終的には問題ありません。うるう秒に関して第 2 レベルの精度を気にする必要がある場合、PHP はおそらくあなたにとって間違った言語です。