2012-04-11 35 views
4
>> $start_dt = new DateTime() 
DateTime::__set_state(array(
    'date' => '2012-04-11 08:34:01', 
    'timezone_type' => 3, 
    'timezone' => 'America/Los_Angeles', 
)) 
>> $end_dt = new DateTime() 
DateTime::__set_state(array(
    'date' => '2012-04-11 08:34:06', 
    'timezone_type' => 3, 
    'timezone' => 'America/Los_Angeles', 
)) 
>> $start_dt->setTimestamp(strtotime('31-Jan-2012')) 
DateTime::__set_state(array(
    'date' => '2012-01-31 00:00:00', 
    'timezone_type' => 3, 
    'timezone' => 'America/Los_Angeles', 
)) 
>> $end_dt->setTimestamp(strtotime('1-Mar-2012')) 
DateTime::__set_state(array(
    'date' => '2012-03-01 00:00:00', 
    'timezone_type' => 3, 
    'timezone' => 'America/Los_Angeles', 
)) 
>> $interval = $start_dt->diff($end_dt) 
DateInterval::__set_state(array(
    'y' => 0, 
    'm' => 0, 
    'd' => 30, 
    'h' => 0, 
    'i' => 0, 
    's' => 0, 
    'invert' => 0, 
    'days' => 30, 
)) 
>> $interval->format('%mm %dd') 
'0m 30d' 

31-Jan-20121-Mar-2012產量不到一個月!我期望輸出爲1個月,1天。二月份的天數應該不重要;這就是使用時間庫的一點 - 它應該處理這些事情。​​。這是PHP的DateTime中的錯誤:diff?

我應該向PHP提交一個錯誤嗎?有沒有一個黑客/修復/解決方法,讓月份按預期工作?

回答

5

我應該向PHP提交一個錯誤嗎?

間隔時間的「月」部分是指開始日期的月份部分可以通過許多個月遞增。 PHP中的行爲將開始日期爲31-Jan-2012並遞增月份(字面意思是31-Feb-2012),然後更正有效日期(PHP會爲您執行此操作)將給出02-Mar-2012,該日期晚於您正在使用的目標日期。

爲了演示這一點,請帶上您的開始日期,並在幾個月內添加n個月以查看行爲。

31-Jan-2012 (Interval) 
02-Mar-2012 (P1M) 
31-Mar-2012 (P2M) 
01-May-2012 (P3M) 
31-May-2012 (P4M) 
01-Jul-2012 (P5M) 

您可以看到月份正在增加,然後調整爲生效日期。

+0

+1,因爲這是正確的答案 - 過去我曾經遇到過這種行爲,並且由於低於恆星的文檔沒有發現這個問題。感謝光照。 :) – Jon 2012-04-11 16:01:04

6

更新答案

DateTime::diff這種行爲肯定是出乎意料的,但它不是一個錯誤。簡而言之,diff返回年,月,日等這樣的,如果你沒有

$end_ts = strtotime('+$y years +$m months +$d days' /* etc */, $start_ts); 

你還是會回到對應於結束原結束日期的時間戳。

這些添加項是「盲目」執行的,然後應用日期更正(例如,1月31日+ 1月將爲2月31日,根據年份更正爲3月2日或3月3日)。在這個具體的例子中,即使在一個月內也不能添加,就像salathe解釋的那樣。

+0

12月1日在間隔([示例](http://codepad.viper-7.com/8wgJI2))中顯示'10'個月。 – salathe 2012-04-11 16:00:01

+0

@salathe:現在我知道 - 正在忙於編輯。 – Jon 2012-04-11 16:01:21

+0

我認爲,幾個月和幾年沒有固定的天數。如果你*問*幾個月,它應該計算兩個日期之間的*日曆*月數;多年來一樣。 *這是*使用庫的優勢;如果我想要一個「客觀」(讀取:一致)天數,我只需拿兩個時間戳,然後除以[2629743.83](https://www.google.ca/search?sourceid=chrome&ie=UTF-8&q =數的+秒+ +在+ A +月)。 – mpen 2012-04-11 16:01:30