如何在PHP的DateTime中启用对Leap Seconds的完整UTC支持?

hak*_*kre 5 php datetime leap-second

我想DateTimeLeap Seconds进行一些计算,但是它很早就停止了,因为我听不懂DateTime我的意思:

### June 30, 2012 at 23:59:60 UTC ###

$leap = new DateTime('2012-06-30T23:59:60UTC');
var_export($leap);
Run Code Online (Sandbox Code Playgroud)

输出:

DateTime::__set_state(array(
   'date' => '2012-07-01 00:00:00',
   'timezone_type' => 3,
   'timezone' => 'UTC',
))
Run Code Online (Sandbox Code Playgroud)

我无法为DateTime去年的UTC leap秒创建一个(我尝试过的其他leap秒也无法创建)。我想知道是否完全DateTime支持leap秒,我以为它支持UTC,但可能不支持leap秒,所以仅支持GMT吗?

Cha*_*les 1

这不完全是一个答案,但至少是一个答案。

这里有两个可能的问题:

  1. 正如 ircmaxell 所提到的,PHP 可能会在时区操作位内的某个地方吃掉闰秒,但还需要更多的研究。
  2. 然而,我个人期望 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)
Run Code Online (Sandbox Code Playgroud)

不幸的是,它还需要 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) ""
}
Run Code Online (Sandbox Code Playgroud)

或者不在午夜:

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) ""
}
Run Code Online (Sandbox Code Playgroud)

此外,它完全是一种演示功能,不DateTime以任何方式附加。你无法对它进行数学计算,考虑到事物的明确定义,在现实生活中从中获得真正的闰秒也是不可能的。这里没啥用。

结论:PHP 不考虑闰秒。确保你的服务器与关心它的上游 NTP 服务器同步你最终会没事的。如果您需要关心闰秒的秒级精度,那么 PHP 可能不适合您。