5

我想用Leap SecondsDateTime做一些计算,但它很早就停止了,因为我不知道我的意思:DateTime

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

$leap = new DateTime('2012-06-30T23:59:60UTC');
var_export($leap);

输出:

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

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

4

2 回答 2

3

UNIX 时间不知道闰秒。就它而言,每一天正好由 86,400 秒组成,而时间只是偶尔跳过或重复一秒。(这在很大程度上是必要的,因为闰秒没有完全提前安排。如果闰秒在 UNIX 时间中计算,则 UNIX 时间和人类可读日期/时间之间的“映射”将随着闰秒的宣布而发生不可预测的变化.)

由于它的日期/时间原语都是基于 UNIX 时间,PHP 也不能轻易地表示闰秒。它们实际上是不可见的。

于 2013-01-08T03:53:48.917 回答
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)

不幸的是,它还需要在 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 可能对您来说是错误的语言。

于 2013-01-08T03:30:19.767 回答