2014-01-15 65 views
-1

我有一个计算两个日期之间的天差的函数:PHP 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.org3v4l.org运行mktime(0, 0, 0, 10, 14, 2014)返回1413237600PHP versions 5.1.0 - 5.5.8
功能的具有这些值的输出是14运行mktime(0, 0, 0, 10, 28, 2014)返回1414450800PHP versions 5.1.0 - 5.5.8

在我的代码中,当我在mktime上运行相同的值时,我分别得到14144616001413255600。运行此代码的函数的输出是13

而我正在运行PHP 5.3.3

任何帮助了解我的环境/ php配置/功能错误/错误代码的错误将不胜感激。

+2

在您的php.ini文件中定义的默认时区设置中,您的日期之间是否存在夏时制转换? –

+0

这两个时间戳之间的差异是13天23小时。所以必须有DST变化。 – Barmar

+1

尝试使用'round()'而不是'floor()'。 – Barmar

回答

3

使用日期时间,而不是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

+0

这是什么原因的投票呢? – vascowhite

+0

嗯,我认为这个问题与DST有关。将尝试与您的答案。 – MurifoX

+0

@MurifoX是的,我在答案中解释。 – vascowhite

1

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

0

功能返回mktime()基于当前时区设置。

如果您希望返回GMT日期的时间戳,那么只需使用函数gmmktime()即可。

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