2014-01-15 66 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被忽略。