PHP mktime地狱

时间:2014-01-15 10:52:45

标签: php date mktime

我有一个计算两个日期之间天差的函数:

function daysBetweenDates($startDate, $endDate) {
  list($year1, $month1, $day1) = explode('-', $startDate);
  list($year2, $month2, $day2) = explode('-', $endDate);
  $f = mktime(0, 0, 0, $month2, $day2, $year2);
  $i = mktime(0, 0, 0, $month1, $day1, $year1);
  $difference =  $f - $i;
  $days = floor($difference/86400);
  return $days;
}

问题是这段代码在某些日期得到了奇怪的结果。例如,如果$startDate = '2014-10-14'$endDate = '2014-10-28',此函数的输出位于14,但我得到13
我已经检查了一些在线PHP解释器,并且由于一些该死的原因我不知道为什么,我的mktime给了我不同的值。

示例:

运行3v4l.org的{​​{1}}上的

会为mktime(0, 0, 0, 10, 28, 2014)返回1414450800 PHP versions 5.1.0 - 5.5.8正在3v4l.org mktime(0, 0, 0, 10, 14, 2014)返回1413237600的{​​{1}} 具有这些值的函数的输出为PHP versions 5.1.0 - 5.5.8

在我的代码中,当我在14上运行相同的值时,我分别得到mktime1414461600。运行此代码时,函数的输出为1413255600

我在13上运行。

任何有关理解我的环境/ php配置/功能错误/错误代码有什么问题的帮助都将非常感激。

3 个答案:

答案 0 :(得分:3)

使用DateTime而不是mktime会结束你的地狱: -

function daysBetweenDates($startDate, $endDate) {
  $startDate = new \DateTime($startDate);
  $endDate = new \DateTime($endDate);
  return $startDate->diff($endDate)->days;
}

应该让你接近你需要的东西。它将考虑到引擎盖下的任何DST变化,这可能是您的问题,因为DST(无论如何在英国)将于今年10月26日结束。

对于您的示例日期,这会返回14

参考http://php.net/datetime

答案 1 :(得分:1)

mktime的值取决于您当前的时区。您为mktime提供的值是“挂钟时间”,它返回绝对的人类历史记录UNIX时间戳。为此,需要考虑您的当前时区,由date_default_timezone_set设置。如果在这两次之间存在DST转换,则在这两个挂钟时间之间可能比其他时区更多或更少。因此,一天不能保证完全是86400秒,你在这里遇到了这个问题。简而言之:这是一种太天真的时差计算方法,因为你忽略了所有使人类时代如此混乱的因素。请参阅@ vascowhite的答案,了解如何使用现有的库来考虑所有这些因素。

答案 2 :(得分:0)

函数返回mktime()基于当前时区集。

如果您希望返回GMT日期的时间戳,请使用函数gmmktime()

或者,您可以将函数$is_dst中的参数mktime()设置为0,这意味着会忽略DST。