这不是一个完整的答案,但至少它是一些东西。
这里有两个可能的问题:
- 正如 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 服务器同步,您最终会没事的。如果您需要关心闰秒的秒级精度,那么 PHP 可能对您来说是错误的语言。