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'

つまり、1 か月未満の収量になります31-Jan-20121-Mar-2012出力は1か月と1日になると思います。2 月の日数は関係ありません。それが時間ライブラリを使用するポイントです。これらを処理することになっています。WolframAlpha は同意します。

PHP にバグを報告する必要がありますか? 何ヶ月も期待どおりに機能させるためのハック/修正/回避策はありますか?

4

2 に答える 2

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 も説明しているように、1 か月も追加できません。

于 2012-04-11T15:46:30.723 に答える
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)

月が増分され、有効な日付になるように調整されていることがわかります。

于 2012-04-11T15:52:26.083 に答える